Socket programming - you have to handle exactly which sockets are being used, you specify TCP or UDP, you handle all the formatting of messages travelling between client and server. However, if you have an existing program that talks over sockets that you want to interface to, it doesn't matter what language it's written in, as long as message formats match.
RMI - hides much of the network specific code, you don't have to worry about specific ports used (but you can if you want), RMI handles the formatting of messages between client and server. However, this option is really only for communication between Java programs. (You *could* interface Java RMI programs with programs written in other languages, but there are probably easier ways to go about it...)
Write once, run anywhere, because there's nowhere to hide! - /. A.C.