lire et écrire sur le même socket (TCP) en utilisant select

Nous sommes en train d'écrire un client et un serveur pour le faire (ce que je croyais) assez simple réseau de communications. Plusieurs clients se connectent au serveur, qui puis est censé envoyer les données en arrière pour tous les autres clients.

Le serveur se trouve juste en bloquant select boucle d'attente pour le trafic, et quand il vient, envoie les données pour les autres clients. Cela semble très bien fonctionner.

Le problème, c'est le client. En réponse à une lecture, il sera parfois amené à faire une écriture.

Cependant, j'ai trouvé que si j'utilise:

 rv = select(fdmax + 1, &master_list, NULL, NULL, NULL);

Mon code bloque jusqu'à ce qu'il y a de nouvelles données à lire. Mais parfois (de manière asynchrone, à partir d'un autre thread) je vais avoir des nouvelles données à écrire sur le réseau de communication thread. Donc, je veux que mon sélectionnez réveiller périodiquement et laissez-moi vérifier si il y a des données à écrire, comme:

if (select(....) != -1)
{
  if (FD_SET(sockfd, &master_list))
     //handle data or disconnect
  else
     //look for data to write and write() /send() those.
}

J'ai essayé le réglage de la sélectionner pour interroger le mode (ou ridiculement court délais d'attente) avec:

//master list contains the sockfd from the getaddrinfo/socket/connect seq
struct timeval t;
memset(&t, 0, sizeof t);
rv = select(fdmax + 1, &master_list, NULL, NULL, &t);

mais ont trouvé que puis ensuite le client ne reçoit jamais de données entrantes.

J'ai aussi essayé le réglage de la prise fd non-blocage, comme:

fcntl(sockfd, F_SETFL, O_NONBLOCK);

mais qui ne résout pas le problème:

  1. si mon client select() n'a pas de struct timevalla lecture des données fonctionne, mais il n'a jamais débloque à me regarder pour l'écriture de données.
  2. si mon client select() a un timeval de l'obtenir pour un sondage, puis il n'a jamais signaux qu'il existe des données entrantes à lire, et mon application se fige la pensée il n'y a pas de connexion au réseau fait (malgré le fait que tous les autres appels de fonction ont réussi)

Tous les pointeurs du tout à ce que je pouvais faire de mal? N'est-il pas possible de faire de la lecture-écriture sur le même socket (je ne peux pas croire que c'est vrai).

(EDIT: La réponse correcte, et chose que je me suis rappelé sur le serveur mais pas sur le client, c'est d'avoir un deuxième fd_set, et copie master_list avant chaque appel à select():

//declare and FD_ZERO read_fds:
//put sockfd in master_list

while (1)
{
   read_fds = master_list;
   select(...);

   if (FD_ISSET(read_fds))
     ....
   else
     //sleep or otherwise don't hog cpu resources
}

)

source d'informationauteur MarcWan