2 votes

Quand le socket du client doit-il être lié pour recevoir des messages UDP d'un serveur ?

J'ai vu deux exemples qui illustrent comment la socket du client peut recevoir des messages du serveur.

Exemple 1 :

code du serveur http://man7.org/tlpi/code/online/book/sockets/ud_ucase_sv.c.html

code client http://man7.org/tlpi/code/online/book/sockets/ud_ucase_cl.c.html

Le programme client crée un socket et le lie à une adresse, afin que le serveur puisse envoyer sa réponse.

if (bind(sfd, (struct sockaddr *) &claddr, sizeof(struct sockaddr_un)) == -1)
    errExit("bind"); // snippet from ud_ucase_cl.c

Exemple 2 :

code du serveur http://man7.org/tlpi/code/online/book/sockets/i6d_ucase_sv.c.html

code client http://man7.org/tlpi/code/online/book/sockets/i6d_ucase_cl.c.html

Dans l'exemple 2, le code client ne lie pas son socket à une adresse.

Question :

Est-il nécessaire que le code du client lie le socket à une adresse afin de recevoir un message du serveur ?

Pourquoi, dans le premier exemple, devons-nous lier le socket du client à une adresse, et pourquoi n'avons-nous pas besoin de le faire dans le second exemple ?

1voto

Kerrek SB Points 194696

Pour le client (TCP) ou l'expéditeur (UDP), l'appel à bind() est facultatif ; il permet de spécifier l'interface. Supposons que vous disposiez de deux interfaces, toutes deux routables vers votre destination :

eth0: 10.1.1.100/24
eth1: 10.2.2.100/24

route: 10.1.1.0/24 via 10.2.2.254  # router for eth1
       0.0.0.0     via 10.1.1.254  # general router

Il suffit de dire connect() a 12.34.56.78 Vous ne savez pas quelle interface locale fournit le côté local de la connexion. En appelant bind() Tout d'abord, vous devez préciser ce point.

Il en va de même pour le trafic UDP : Sans bind() tion, votre sendto() utilisera une adresse et un port source aléatoires, mais avec l'option bind() vous précisez la source.

1voto

Nikolai N Fetissov Points 52093

La différence est que le socket family - Le premier exemple utilise AF_UNIX , tandis que le second fait AF_INET6 . D'après le Stevens UNP vous devez explicitement bind à la socket du client Unix afin que le serveur dispose d'un chemin d'accès auquel il peut envoyer sa réponse :

... l'envoi d'un datagramme à une socket de datagramme de domaine Unix non liée ne lie pas implicitement un chemin d'accès à la socket. Par conséquent, si nous omettons cette étape, l'appel du serveur à recvfrom ... renvoie un nom de chemin nul ...

Cela n'est pas nécessaire pour les INET{4,6} puisqu'elles sont liées automatiquement à un port éphémère.

1voto

blaze Points 2930

Si vous n'avez pas lié la socket du client AF_INET/AF_INET6 avant de vous connecter ou d'envoyer quelque chose, la pile TCP/IP la liera automatiquement au port éphémère de l'adresse de sortie.

Contrairement à cela, les sockets de domaine UNIX (AF_UNIX) ne se lient pas automatiquement lors de l'envoi, de sorte que vous pouvez envoyer des messages via SOCK_DGRAM sans recevoir de réponse.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X