Probleme de select()

Probleme de select() - C++ - Programmation

Marsh Posté le 20-05-2004 à 16:13:59    

Bonjous,  
ben voila je voudrait utiliser un select avec un recv mais qu'and j'envoi sur mon serveur le select qui gere la reception me renvoi TTT 0.donc po de lecture sur ma socket.  
je voudrais savoir si je m'y prend bien pour mon select:  
 

Code :
  1. SOCKET sockclient;
  2. ioctlsocket(sockclient,FIONBIO,(unsigned long *)1);
  3. for (;;)
  4. {
  5.          FD_ZERO(&fdread);
  6.          FD_SET(sockclient,&fdread);
  7. if (ret =select(0,&fdread,NULL,NULL,&seltimeout)==SOCKET_ERROR)cout<<"select error"<<endl
  8.      
  9.      if (ret!=0)cout  <<"La valeur de ret select :"<<ret<<endl;
  10.    
  11.       if (ret > 0)
  12.         {
  13.                    if (FD_ISSET(sockclient,&fdread))
  14.             {
  15.                if ( recv(sockclient,buf,16,0)==-1)cout <<"reception   ECHEC:!"<<endl;
  16.                  
  17.               }
  18.          }
  19. }


 

Reply

Marsh Posté le 20-05-2004 à 16:13:59   

Reply

Marsh Posté le 20-05-2004 à 16:44:55    

Tu devrais faire un WSAGetLastError() pour vérifier précisement d'ou vient le problème...
 
si le code de retour est 0, c'est ton timeout qui expire et qui n'est sans doute pas correctement defini...
 
Sinon je suis pas sur, mais tu as rendu ta socket non bloquante non ? c'est peut etre ca le problème...


---------------
- Pierre Baudelet -
Reply

Marsh Posté le 20-05-2004 à 18:50:53    

non ya po du tou d'ereur avec getlast error
enfet select renvoi zero , si yavaait erreu y renverer socket error  
sa ve dire qu ya zero socket en reception pourtan quand je conect un client avec le select du conect  renvoit 1 donc sa marche mais quant je fait le send  
via le client le select du recv ne renvoi po de socket en cour de lecture donc 0 tous le temp je compren po....
ps :avec ou sans time out sa marche po  
 bon je lache le code complet:
 

Code :
  1. int main()
  2. {
  3. WSADATA WSAData;
  4. WSAStartup(MAKEWORD(2,0), &WSAData);
  5. int NbrClient = 0 ;
  6. SOCKET sockclient = 0;
  7. SOCKET con;
  8. SOCKADDR_IN client;
  9. SOCKADDR_IN conect;
  10. int ret=0;
  11. unsigned long ul = 1;
  12. int retSelect=0;
  13. int clen =sizeof(client);
  14. int flen =sizeof(conect);
  15. con=socket(AF_INET,SOCK_STREAM,0);
  16. conect.sin_addr.s_addr   = htonl(INADDR_ANY);
  17. conect.sin_family   = AF_INET;
  18. conect.sin_port    = htons(4148);
  19. bind(con, (SOCKADDR *)&conect, sizeof(conect));
  20. //----------------------------------------------------
  21. fd_set fdread;
  22. char *buf=new char [16];
  23. struct timeval seltimeout;
  24. DWORD  RecvSend;
  25. seltimeout.tv_usec= 10;
  26. seltimeout.tv_sec=21;
  27. //--------------ger e les conection sur le acept
  28.   listen(con, 0);
  29.   while (true)
  30.   {
  31.      FD_ZERO(&fdread);                 //met le set a 0
  32.      FD_SET(con, &fdread);
  33.      int ret = select(0, &fdread, 0, 0, 0);
  34.      if (ret >0)
  35.         {
  36.         cout << "valeur du acept :"<< ret<<endl;
  37.   sockclient = accept(con, (SOCKADDR *)&client,&clen ) ;
  38.   ret = ioctlsocket(sockclient,FIONBIO,(unsigned long *)1);
  39.     if (ret == SOCKET_ERROR)cout <<"Impossible de passer en nomblocking mode....!"<<endl;
  40.    else {cout << "NOMBLOCKING ACTIVED SOCKET"<<endl;cout <<"::"<<ret<<endl; }
  41.                    FD_ZERO(&fdread);
  42.           cout << "le socket du client ="<<sockclient<<endl;
  43.           FD_SET(sockclient,&fdread);
  44.           NbrClient++;
  45.            cout <<"Nombre de client:"<<NbrClient<<endl;
  46.          }
  47.    //for nbrc}
  48. //----------------------------rer-re-ere-erere-
  49. //------ gere la reception
  50. if  (NbrClient >0)
  51.   {
  52.      if (ret =select(0,&fdread,NULL,NULL,&seltimeout)==SOCKET_ERROR)cout<<"select error"<<endl;//else cout <<"select ok!!!!!!!"<<endl;
  53.      // cout << GetLastError()<<endl;
  54.      if (ret!=0)cout  <<"La valeur de ret select "<<ret<<endl;
  55.      // Sleep(1000);
  56.       if (ret > 0)
  57.         {
  58.          cout <<" un SOCKETR est en cour de lecture"<<endl;
  59.           if (FD_ISSET(sockclient,&fdread))
  60.             {
  61.                if ( recv(sockclient,buf,16,0)==-1)cout <<"reception du nom ECHEC:!"<<endl;
  62.                  
  63.                                 }
  64.         }
  65.     }
  66. }
  67. // fin du programme


Message édité par tckoullou le 20-05-2004 à 19:09:29
Reply

Marsh Posté le 20-05-2004 à 20:32:08    

Et en Français ??  :o

Reply

Marsh Posté le 20-05-2004 à 21:17:57    

le select renvoi tous le temp 0 sur mon socket client coté serveur....
est ce qui fo faire un send classique coter client ??
 
ben en grod je voudrait un code d'exemple pour faire un select() sur un recv()


Message édité par tckoullou le 20-05-2004 à 21:57:38
Reply

Marsh Posté le 20-05-2004 à 22:10:42    

eh ben voila ya qu'a demander ;)
 
C'est une fonction d'attente d'arrivée de données (pour une reponse à un ping en raw sockets)
 

Code :
  1. int CPing::IsDataAvailable()
  2. {
  3. int iErr = ERR_WSA_OK; // code d'erreur renvoyé, par défaut tout va bien
  4. CNWScanException *e = NULL; // exception au cas ou...
  5. e = new CNWScanException;
  6. if(!e)
  7.  return ERR_EXP_CREATE;
  8. // structure utilisée par select contenant une durée en secondes et en microsecondes
  9. timeval timeout = {m_dwTimeout/1000, (m_dwTimeout % 1000) * 1000};
  10. fd_set fds; // file descriptor qui permet d'associer une socket a des opérations de lecture/ecriture
  11. FD_ZERO(&fds); // macro qui initialise le fds
  12. FD_SET(m_Socket, &fds); // macro qui associe la socket au fds
  13. // On attend avec un timeout sur les opérations de lecture
  14. iErr = select(0, &fds, NULL, NULL, &timeout);
  15. if(iErr == 0 || iErr == SOCKET_ERROR)
  16. {
  17.  // un timeout a eu lieu, le buffer de reception est vide
  18.  e->SetErrorCode(ERR_WSA_TIMEOUT);
  19.  throw e;
  20. }
  21. // tout va bien le buffer contient des données
  22. delete e;
  23. return ERR_WSA_OK;
  24. }


 
et le bloc de code avant réception qui se sert du select:
 

Code :
  1. try
  2. {
  3.  // Attente de réception de données dans le buffer avec timeout
  4.  err = IsDataAvailable();
  5. }
  6. catch (CNWScanException *se)
  7. {
  8.  // rien n'est recu apres timeout
  9.  // on nettoie tout et on sort
  10.  Cleanup(pPacket, pRecvBuf);
  11.  e->SetErrorCode(se->GetLastError());
  12.  throw e;
  13. }
  14. // la réponse est la ...
  15. // on alloue un buffer de réception
  16. pRecvBuf = new char[MAX_PACKET_SIZE];
  17. if(!pRecvBuf)
  18. {
  19.  // erreur, on nettoie ce qui est alloué et on sort...
  20.  e->SetErrorCode(ERR_MEM_ALLOC);
  21.  Cleanup(pPacket);
  22.  throw e;
  23. }
  24. // on lit les données recues, on obtient des infos sur l'emetteur dans from
  25. nRead = recvfrom(m_Socket, pRecvBuf, MAX_PACKET_SIZE, NULL, (sockaddr *)&from, &fromLen);
  26. if(nRead == SOCKET_ERROR)
  27. {
  28.  // impossible de lire sur la socket
  29.  // on nettoie tout et on sort
  30.  e->SetErrorCode(ERR_WSA_NOK);
  31.  Cleanup(pPacket, pRecvBuf);
  32.  throw e;
  33. }


---------------
- Pierre Baudelet -
Reply

Marsh Posté le 21-05-2004 à 09:37:26    

:jap: yes je te remerci pedro je vais tester sa !


Message édité par tckoullou le 21-05-2004 à 09:37:52
Reply

Marsh Posté le 21-05-2004 à 12:10:48    

:jap: ok c'est bouen sa marche enfet javait deja piger le concept et ton code ma permis d'etre sur d'insister dans la bone voi je te remerci


Message édité par tckoullou le 21-05-2004 à 12:12:46
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed