Erreur de liaison lors de la recréation du socket

A ont le socket d’écouteur suivant:

int sd = socket(PF_INET, SOCK_STREAM, 0); struct sockaddr_in addr; bzero(&addr, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(http_port); addr.sin_addr.s_addr = INADDR_ANY; if(bind(sd,(sockaddr*)&addr,sizeof(addr))!=0) { ... } if (listen(sd, 16)!=0) { ... } int sent = 0; for(;;) { int client = accept(sd, (sockaddr*)&addr, (socklen_t*)&size); if (client > 0) { ... close(client); } } 

Si une utilisation

 close(sd); 

et en essayant ensuite de recréer une socket avec le même code, une erreur de liaison se produit, et seulement 30 à 60 secondes plus tard, une nouvelle socket est créée avec succès.

Y at-il un moyen de créer ou de fermer de façon sympa pour éviter les erreurs de reliure?

Quelque part dans le kernel, il rest encore des informations sur votre précédent socket. Indiquez au kernel que vous souhaitez quand même réutiliser le port:

 int yes=1; //char yes='1'; // use this under Solaris if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) { perror("setsockopt"); exit(1); } 

Reportez – vous à la section bind () du Guide de programmation réseau de beej pour une explication plus détaillée.

C’est le comportement attendu pour les sockets TCP. Lorsque vous fermez un socket, il passe à l’état TIME_WAIT. Il acceptera et lâchera des paquets pour ce port. Vous devez définir l’option SO_REUSEADDR pour une liaison immédiate.

Vous ne devriez pas fermer le socket lié et ensuite essayer de le recréer.

accept retourne un socket nouvellement créé pour cette connexion, c’est celui qui doit être fermé. c’est-à-dire que vous devriez faire –

 close(client); 

Essayez d’appeler setsockopt avec SO_REUSEADDR . Reportez-vous à: http://msdn.microsoft.com/en-us/library/ms740476(v=vs.85).aspx