Concernant la portabilité de code faut bien se dire que d'un OS à un autre, ça va engendrer du code en plus, c'est pas rigoureusement le même code que l'on compile à la fois pour windows et pour linux.
Pour être concret, sous windows avec l'api winsock2 on utilisera par exemple closesocket() tandis que sous linux les sockets de type Berkeley étant assimilées à des descripteurs de fichier standard, on fermera une socket avec un simple close() comme on ferme un fichier au niveau du système.
La solution c'est de mettre une ligne :
#define closesocket close
d'un coté où de l'autre de la portabilité, de manière que dans un cas, closesocket() existe, pas de problème, dans l'autre cas "closesocket" est remplacé à la pré-compilation par "close", et donc ça marche aussi...
Egalement une caractéristique de Winsock c'est qu'il faut l'initialiser avec WSAStartup(), chose dont on se fout éperduement avec les socket BSD.
De fait on shinte le bazar en insérant le code spécifique à windows à l'interieur de directives pré-processeur :
#ifdef __WIN32__
WSADATA wsa;
WSAStartup (MAKEWORD (2,2), &wsa);
#endif
et ce code là n'interresse pas le moins du monde le compilateur sous linux, de fait ce bout de code n'est effectivement compilé que lorsqu'on build sous windows, cqfd.
Sans doute mieux qu'un long discours, un exemple de code d'un client TCP portable Win/Lin
ici.
BufferBob.