J'ai un programme de serveur de réseau axé sur les événements. Ce programme accepte les connexions d'autres processus sur d'autres hôtes. Il peut y avoir de nombreuses connexions de courte durée provenant de différents ports sur la même adresse IP distante.Avec accept() et select() en même temps?
Actuellement, j'ai une boucle while(1)
qui appelle accept()
, puis engendre un thread pour traiter la nouvelle connexion. Chaque connexion est fermée après la lecture du message. À l'extrémité distante, la connexion est fermée après l'envoi d'un message.
Je veux éliminer le surcoût lié à l'établissement et à l'arrêt des connexions en mettant en cache les FD ouverts de socket. Du côté de l'expéditeur, c'est facile - je ne ferme pas les connexions et les garde. Du côté du récepteur, c'est un peu plus difficile. Je sais que je peux stocker le FD retourné par accept()
dans une structure et écouter les messages à travers toutes les sockets en utilisant poll()
ou select()
, mais je veux simultanément à la fois écouter les nouvelles connexions via accept()
et écouter sur toutes les connexions en cache.
Si j'utilise deux fils, l'un sur poll()
et un sur accept()
, puis quand l'appel retourne accept()
(est ouvert une nouvelle connexion), je dois réveiller l'autre thread en attente sur l'ancien ensemble de connexions. Je sais que je peux le faire avec un signal et pselect()
, mais tout ce gâchis semble beaucoup trop de travail pour quelque chose d'aussi simple.
Existe-t-il un appel ou une méthodologie supérieure qui me permettra de gérer simultanément les nouvelles connexions ouvertes et les données envoyées sur les anciennes connexions?
Hmm, c'est une condition de concurrence bien connue - le 'accept (2)' bloquera si le client abandonne la tentative de connexion entre deux appels système. Vous avez besoin que la prise d'écoute soit non bloquante. –
Ceci est correct - vous pouvez ajouter votre descripteur de fichier d'écoute à 'readfds' dans votre appel' select() ', et' select() 'vous dira que le descripteur de fichier est" lisible "s'il a une connexion prête à' accepter() '. @Nikolai est correct aussi - le socket d'écoute doit être non bloquant et l'appel 'accept()' préparé pour gérer 'EAGAIN'. – caf