Quand un connecté UDP socket être fermé par l'OS?
J'ai un UDP descripteur de fichier dans un programme C++ fonctionnant sous Linux. J'appelle connect()
sur elle pour se connecter à une adresse distante, puis lire et à écrire à partir de cette prise.
Selon UNIX Réseau de Programmation, "Asynchrone erreurs sont renvoyées au processus pour les sockets UDP." Je devine que ces erreurs asynchrones sera la cause de la socket UDP être fermée par le système d'exploitation, mais le livre n'est pas clair. Il n'est pas clair quels sont les types d'erreurs asynchrones sont possibles, mais il est suggéré que, si le port sur la machine distante n'est pas ouvert, le socket est fermé.
Donc ma question est: dans quelles conditions Linux fermer l'UDP descripteur de fichier?
- Mauvais numéro de port?
- Mauvaise adresse IP?
- Tout les autres?
- Socket UDP ne peut pas être connecté, cochez en.wikipedia.org/wiki/Berkeley_sockets#Client_2
- Non, ils peuvent lire la page de man pour connect(): "Si s est de type SOCK_DGRAM, il spécifie de façon permanente par les pairs à laquelle les messages sont envoyés." Comme je l'ai mentionné dans la question, UNIX Réseau de Programmation des états que des erreurs asynchrones sera retourné pour connecté les sockets UDP.
Vous devez vous connecter pour publier un commentaire.
connect() sur une socket UDP enregistre simplement le numéro de port et l'adresse IP que vous transmettez, afin d'accepter uniquement les paquets à partir de cette adresse IP/port, et vous pouvez utiliser la prise fd pour envoyer/écriture de données sans préciser l'adresse à distance pour chaque envoi/appel d'écriture.
À ce sujet, async erreurs signifie que si vous envoyez() quelque chose, et qui envoient des résultats des appels à une erreur se produisant plus tard (par exemple lorsque la pile TCP/IP envoie le paquet, ou un paquet ICMP est retourné plus tard), un envoyer sera de retour cette erreur. Ces async erreurs sont renvoyées sur un "connecté" socket UDP. (Linux udp(7) page de manuel suggèrent les erreurs sont retournées si le socket est connecté ou pas, mais les tests montrent que ce n'est pas le cas, au moins quand pour envoyer un paquet UDP génère une erreur ICMP. Il se pourrait que send() les erreurs sont retournées si vous recv() sur ce socket, au lieu de la suite send() appelle produire une erreur )
Le socket n'est pas fermé, vous devrez fermer vous-même, soit par l'appel à close() ou quitter le programme. par exemple, si vous vous connectez() de votre socket UDP et envoyez-le à un port personne n'est à l'écoute, un paquet ICMP est normalement de retour et ensuite de l'envoyer() l'appel échoue avec errno à ECONNREFUSED. Vous pouvez continuer à envoyer sur ce socket cependant, il n'est pas fermée par le système d'exploitation, et si quelqu'un se met à l'écoute sur le port dans le temps, les paquets vont passer à travers.
Les sockets UDP sont sans connexion, donc il n'y a pas de sens réel de "l'ouverture" de l'état joint à eux - c'est la différence de sockets TCP où un socket peut être n'importe quel nombre d'états de connexion tel que déterminé par l'échange de paquets jusqu'à un point donné.
Le seul sens dans lequel les sockets UDP peut être ouvert et fermé est en ce sens qu'ils sont de niveau système des objets avec un certain état interne et un descripteur de fichier. Les Sockets ne sont jamais fermés automatiquement en cas d'erreur et le restera indéfiniment, à moins que leur propriétaire processus se termine, ou des appels
close
sur eux.Pour répondre à votre autre question, si le port de destination sur l'hôte de destination n'est pas ouvert, l'expéditeur d'un paquet UDP ne le saura jamais.** UDP ne fournit aucun moyen de récepteur d'accusé de réception. Le paquet est routé et, s'il arrive à l'accueil, vérifie qu'il est correct et soit correctement reçu ou mis au rebut. Il y a un certain nombre de raisons pour lesquelles
send
peut renvoyer un code d'erreur lors de l'écriture sur un socket UDP, mais aucun d'entre eux ont à voir avec l'état de l'hôte.** Je vous recommande de consulter lesendto
page de manuel pour possible des modes de défaillance.D'autre part, dans le cas d'un socket TCP tente de se connecter à un port non ouvert, l'expéditeur ne sera plus jamais recevoir un accusé de réception de sa première demande de connexion, et, finalement,
connect
échouera. À ce stade, il serait à l'expéditeur d'arrêter d'envoyer des données sur le support (ce qui ne génère plus d'erreurs), mais même dans ce cas cependant, la prise de descripteur de fichier n'est jamais fermée automatiquement.** Voir la réponse par @Zuljin dans les commentaires.
Le système d'exploitation ne fermez pas votre prise juste parce qu'une erreur s'est produite. Si l'autre extrémité disparaît, vous pouvez continuer à envoyer des messages (mais peut recevoir plus d'erreurs).