2010-06-03 5 views
4

Mon socket UDP initial est lié à 127.0.0.1: 9898.comment lier/connecter plusieurs socket UDP

La première fois que je reçois une notification de données entrantes par epoll/kqueue, je recvfrom() et je remplis un struct sockaddr appelé peer_name qui contient les informations d'homologue (ip: port).

Puis-je créer une nouvelle prise à l'aide de la prise UPD(),

je bind() cette prise nouvellement créée à la même adresse IP: port (127.0.0.1:9898) que ma prise d'origine.

puis je connecte mon socket nouvellement créé en utilisant connect() à l'homologue qui vient de m'envoyer quelque chose. J'ai l'information dans la structure sockaddr appelée peer_name. Puis j'ajoute ma nouvelle socket dans mon vecteur epoll/kqueue et j'attends la notification.

Je m'attendrais à recevoir UNIQUEMENT une trame UDP du pair auquel je suis "" connecté à "".

1/est netstat -a -p udp est supposé me montrer l'IP: PORT de l'homologue mon socket nouvellement créé est "" connecté à ""?

2/Je fais probablement quelque chose de mal puisque après avoir créé mon nouveau socket, ce socket reçoit tous les paquets UDP entrants destinés à l'IP: PORT auquel je suis lié, quel que soit l'IP source: PORT.

Je voudrais voir un exemple de travail de ce que j'essaie de faire :) ou tout indice sur ce que je fais mal.

merci!

Répondre

1

connexion (2) sur un socket UDP définit simplement l'adresse de destination par défaut de la prise (où les données seront envoyées si vous utilisez write (2) ou envoyer (2) sur la prise) . Il n'a aucun autre effet - vous pouvez toujours envoyer des paquets à d'autres adresses avec sendto (2) ou sendmsg (2) et vous verrez toujours les paquets envoyés à partir de n'importe quelle adresse.

Il n'est donc pas vraiment logique d'ouvrir un nouveau socket sur le port - pour chaque paquet reçu, vous devez regarder l'adresse source pour voir si elle provient d'une adresse déjà vue (et appartient donc à ce flux logique) ou est une nouvelle adresse (un nouveau flux logique).

+0

Juste pour être sûr, je parle du côté du serveur. L'idée, c'est que le nouveau socket recevra toutes les données d'un client spécifique. C'est pourquoi je connecte() mon nouveau socket au client source IP: PORT. Une socket en tant que nom de connexion et nom d'utilisateur.Le sockname est l'ADDR: PORT auquel le socket est lié, et le peername est l'ADDR: PORT auquel le socket est associé (en utilisant connect()) et donc send() sait à qui envoie les données. getsockname(), getpeername(). – nicboul

+0

@nicboul: Oui. Ce que Chris fait remarquer c'est que 'connect()' sur une socket UDP n'est généralement utile que du côté * client *, où une seule socket ne parle qu'à un seul pair. Ce n'est pas utile du côté du serveur. – caf

+1

@Chris Je vais être en train de choisir, mais je ne suis pas sûr d'être d'accord avec votre déclaration. Je pense que la connexion a l'effet d'une liaison distante-addr afin que vous puissiez restreindre le trafic sur cette socket aux messages d'un client spécifique. Je baser cela dans un 'strace nc -4lu $ ((0x4444))', suivi de 'grep 4444/proc/net/udp' (dans un terminal différent), avant et après la réception du premier message. 'nc' n'acceptera pas les messages d'autres clients. – nhed

4

http://www.softlab.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-5.html

« Est-ce que faire un appel connect() affecte la réception habitudes d'achatdes la prise? Oui, de deux façons. Tout d'abord, que les datagrammes de votre « pairs connectés » sont renvoyés. Tous les autres arrivent à votre port

Mais le plus important, une prise UDP doit être connectée pour recevoir des erreurs ICMP Les pages 748-749 de "TCP/IP Illustrated, Volume 2" donnent tous les détails sanglants sur pourquoi cela est ainsi "

Questions connexes