Principales fonctions de gestion des sockets

 

Includes et librairies

- Includes et librairies à utiliser

 

Création d’un socket

Elle est réalisée par la primitive système socket() : cette fonction va permettre de configurer la connexion.

id = socket(af, type, protocole)

En entrée:
af : famille de protocoles utilisée par le socket

- AF_PUP,
- AF_INET : TCP/IP utilisant une adresse Internet sur 4 octets : l'adresse IP et un numéro de port.

Ceci permet d'avoir plusieurs sockets sur une même machine.
- AF_UNIX : communications UNIX en local sur une même machine.

type : type de communication souhaité :

Les principales étant:

- connecté: SOCK_STREAM (communication par flot de données),
- non connecté: SOCK_DGRAM (utilisation de datagrammes, blocs de données)

protocole : Généralement à 0 (pour TCP/IP), permet de spécifier un protocole permettant de fournir le service désiré.

En sortie, un identifiant sur le socket.

 

Options sur le socket

Il est possible de positionner des options complémentaires sur un socket ou de les récupérer. Il suffit d'utiliser:

Pour positionner:

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

Pour récupérer:

int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);

 

En entrée:

sockId, identifiant du socket à lire ou modifier

level: A positionner à SOL_SOCKET pour indiquer que les manipulations vont se situer au niveau du socket. Sinon indiquez le numéro du protocol correspondant pour atteindre les options correspondantes (voir getprotoent).

optname: options qui correspondent à level utilisé (utiliser | pour concaténer plusieurs options, voir sys/socket.h pour les options disponibles).

optval et optlen correspondent à la valeur des options et la taille occupée par cette valeur.

Ces fonctions retournent 0 si tout est ok, -1 sinon et errno indique le problème

 

Exemple, forcer la réutilisation d'une adresse ou d'un port local, utile pour éviter suite à un plantage le beau message :

bind failed, Error: Adress already in use

setsockopt(idSocket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &(int){ 1 }, sizeof(int))

Héritage d’un socket

Faut-il encore préciser ce genre de chose ?

Sous Unix, lorsque vous utilisez les primitives fork() ou exec() à partir d’un processus ayant ouvert un socket pour lancer une copie du processus ou une autre application ; les accès aux sockets sont transmis aux nouveaux processus ainsi créés. Un compteur de références est associé à chaque socket et indique le nombre de processus possédant un accès sur le socket (cf. Les processus).

 

Fermeture d'un socket

Classique, l’appel close (id) permet de fermer un accès aux sockets et décrémente le compteur associé (compteur pour les héritages éventuels...). (N'oubliez pas de définir l'include: #include <unistd.h> pour unix, io.h pour Windows !)

On lui préfèrera la fonction closesocket(id) sous windows pour une raison de lisibilitée...

Mais il y a aussi la fonction shutdown() qui permet de fermer le socket dans un sens ou dans l'autre...

En fait, le socket va servir pour transmettre des données ou pour en réceptionner. Grâce à cette commande, vous pouvez iniquer dans quel sens sera fermer la communication. Vous pourrez aussi le fermer dans les deux sens, mais alors autant utiliser closesocket () !!!

int shutdown(int socket, int how);

En entrée:

- socket est l'identifiant de socket

- how indique le sens de fermeture avec: 0 pour fermer la socket en réception, 1 en émission, 2 dans les deux sens.

En sortie:

La fonction retourne la valeur -1 en cas d'erreur, sinon elle retourne la valeur 0.