Il faut le faire en deux temps :
1) sérialiser les objets (les transformer en séquence d'octets)
2) envoyer les octets via la socket
L'étape 2 ne devrait pas poser de problème.
Quant à l'étape 1, il te faut définir un protocole et le respecter scrupuleusement des deux côtés. Par exemple, vas-tu encoder une chaîne avec sa taille, ou bien simplement ajouter un 0 terminal ? Vas-tu encoder en big endian ou en little endian (normalement il faut utiliser le "network byte order") ? Si tu utilises TCP, il faut aussi prévoir de borner explicitement les messages, car le protocole TCP peut séparer ou combiner à sa guise ce que tu envoies. Attention aussi à n'utiliser que des types à taille fixe pour éviter des différences entre les deux machines qui communiquent.
Une fois ton protocole défini, il te suffit d'utiliser la méthode qui va bien pour transformer des variables en suites d'octets bruts. Je ne sais pas comment ça se passe en C# mais tu devrais trouver suffisamment de doc sur le sujet.