11
votes

Socket Écouter N'engaudra pas de C ++ sous Linux

J'ai une prise qui écoute sur certains ports. J'envoie le signal SIGSTOP au fil qui attend sur le port (à l'aide d'accepter) et terminez-le. Ensuite, je ferme la FD de la prise que j'ai attendu. Mais pour la prochaine course de mon projet, il ne me permet pas d'écouter à nouveau sur ce port. Mon programme est en C ++ sous Linux. Que dois-je faire?

Certaines parties de mon code sont: Fil 1: P>

listenerFlag = true;
accepterFlag = true;
sleep(1);
pthread_kill(listenerThread, SIGSTOP);
pthread_kill(accepterThread, SIGSTOP);
close(sockfd);
sem_wait(setSem);
for (int i = 1; i <= maxFd; i++) {
if (FD_ISSET(i, &set)) {
    close(i);
}
}
sem_post(setSem);


2 commentaires

Essayez peut-être de fermer la FD de la prise à l'intérieur du fil d'acceptation car il se termine?


Êtes-vous sûr que vous voulez envoyer sigstop ? Est-ce que quelqu'un va envoyer un sigcont plus tard? Je ne serais pas surpris que les sockets ne puissent enfin être fermés tant que certains threads (arrêtés) sont toujours à l'intérieur d'un Accepter appel sur cette prise. (Vous avez dit que vous avez également terminé le fil, je ne vois tout simplement pas ça.)


3 Réponses :


1
votes

1 commentaires

Je sais que. Mais il devrait être fermé. Comment puis-je vraiment le fermer?



1
votes

Je pense que le problème est que vous n'avez pas correctement fermé la prise et / ou votre programme. La prise existe probablement toujours dans le système d'exploitation. Vérifiez-le avec quelque chose comme Nestat -an. Vous devez également vérifier si votre processus est sorti. S'il a correctement terminé, il aurait dû fermer votre prise.

Ce que vous devriez faire est:

  • interrompre votre fil avec un signal.
  • Lors de l'interrompre, votre thread doit proximeusement fermer la prise avant la fin.
  • Vous pouvez ensuite quitter votre programme.

    my2cents,


1 commentaires

D'accord. Ensuite, so_reoseaddr est la clé :-)



23
votes

Saviez-vous que les prises sont généralement conservées dans une sorte de limbe pendant une minute ou deux après avoir fini d'écouter sur eux pour empêcher les communications destinées au processus précédent? Ça s'appelle l'état "Time_Wait".

Si vous souhaitez remplacer ce comportement, utilisez setSockopt pour définir le SO_REUSEADDR Drapeau contre la prise avant d'écouter.


4 commentaires

Vérifiez également SO_LINGER. développeurweb.net/forum/archive/index.php/t- 2982.html


Je savais que dans Java. Est-ce la même chose pour C ++?


Oui, c'est une chose de TCP plutôt que d'une truc de langage afin qu'elle s'applique partout.


Pour les archives, il semble que vous ayez besoin de définir le drapeau SO_REUSEPORTE également sur Apple: int Reusport = 1; setSockopt (socket_, sol_socket, SO_REUSEPORT, & REUNEPORTE, Tailleof (réeus));