Les sockets ne s'utilisent pas de manière identique selon les différents systèmes d'exploitation : je vais donc vous guider tout le long de ce chapitre pour que vous ne quittiez pas le bon chemin

.
Les inclusions et les ressources
Sur Windows
Tout d'abord, n'oubliez pas, dans
chaque projet que vous créez, d'ajouter le fichier
"ws2_32.lib" (pour le compilateur Visual C++) ou
"libws2_32.a" (pour les autres) dans votre éditeur de liens. Vous trouverez ce fichier dans le dossier
"lib" de votre IDE. J'insiste un peu, car on oublie très souvent de le faire

.
Il faut savoir que presque tout ce qui touche aux sockets Windows se trouve dans le fichier
"winsock2.h", dans le dossier
header de votre IDE. Celui-ci est un fichier standard de Windows, il n'y a pas besoin de le télécharger

.
Nous allons donc tout de suite l'inclure dans notre premier programme comme suit :
Code : C
En général, vous aurez besoin des fichiers standards
"stdio.h" et
"stdlib.h".
Nous allons donc aussi les inclure :
Code : C1
2
3 | #include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
|
On peut remarquer que le type socklen_t qui existe sous Linux, n'est pas défini sous Windows. Ce type sert à stocker la taille d'une structures de type sockaddr_in. Ça n'est rien d'autre qu'un entier mais il nous évitera des problèmes éventuels de compilation sous Linux par la suite. Il va donc falloir le définir nous même à l'aide du mot clef typedef comme il suit :
Code : C
De plus, vous devrez ajouter, dans le début de votre fonction
main, le code suivant pour pouvoir utiliser les sockets sous Windows :
Code : C1
2 | WSADATA WSAData;
WSAStartup(MAKEWORD(2,2), &WSAData);
|
La fonction
WSAStartup sert à initialiser la bibliothèque WinSock. La macro MAKEWORD transforme les deux entiers (d'un octet) qui lui sont passés en paramètres en un seul entier (de 2 octets) qu'elle retourne. Cet entier sert à renseigner la bibliothèque sur la version que l'utilisateur souhaite utiliser (ici la version 2,0). Elle retourne la valeur 0 si tout s'est bien passé.
Puis à la fin, placez celui-ci :
Code : C
Cette fonction va simplement libérer les ressources allouées par la fonction WSAStartup().
Sur Linux
Sur Linux, c'est un peu différent puisque les fichiers à inclure ne sont pas les mêmes...
Pour combler l'écart entre Windows et Linux, nous utiliserons des
définitions et des
typedef.
Commençons par inclure les fichiers nécessaires :
Code : C1
2
3
4
5
6
7 | #include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
|
Un premier problème se pose :
Dans le fichier
"socket.h" de Linux, la fonction qui sert à fermer une socket (que nous verrons par la suite) se nomme
close alors que dans le fichier
"winsock2.h" de Windows la fonction se nomme
closesocket ... Pour éviter de faire deux codes sources pour deux OS différents, nous utiliserons une définition comme il suit :
Code : C1 | #define closesocket(param) close(param)
|
Ainsi dans le code la fonction closesocket() sera remplacée par la fonction close() qui pourra ensuite être exécutée.
Le deuxième problème vient du fait qu'il "manque" deux définitions et trois
typedef qui peuvent nous être utile dans le fichier
"socket.h" de Linux par rapport au fichier
"winsock2.h" de Windows.
Voila donc le contenu de notre fichier pour le moment :
Code : C 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | #include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket(param) close(param)
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
|
Sachez qu'il y a beaucoup de fichiers à inclure par rapport à Windows mais qu'ils sont tous utiles.
Un code portable
Pour pouvoir avoir un code un peu plus portable, nous utiliserons les définitions WIN32 et linux.
Cette méthode indiquera à votre compilateur le code à compiler en fonction de votre OS.
Code : C 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 | //Si nous sommes sous Windows
#if defined (WIN32)
#include <winsock2.h>
// typedef, qui nous serviront par la suite
typedef int socklen_t;
// Sinon, si nous sommes sous Linux
#elif defined (linux)
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
// Define, qui nous serviront par la suite
#define INVALID_SOCKET -1
#define SOCKET_ERROR -1
#define closesocket(s) close (s)
// De même
typedef int SOCKET;
typedef struct sockaddr_in SOCKADDR_IN;
typedef struct sockaddr SOCKADDR;
#endif
// On inclut les fichiers standards
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
// Si la plateforme est Windows
#if defined (WIN32)
WSADATA WSAData;
WSAStartup(MAKEWORD(2,2), &WSAData);
#endif
// ICI on mettra notre code sur les sockets
// Si la plateforme est Windows
#if defined (WIN32)
WSACleanup();
#endif
return EXIT_SUCCESS;
}
|