[socket] timeout

timeout [socket] - C++ - Programmation

Marsh Posté le 24-12-2004 à 16:46:07    

Bonjour,
 
En ce moment j'écrit une application reseau qui utilise les socket en mode tcp
 
J'utilise la fonction recv pour recevoir un message
Seulement voila j'ai un petit probleme: lorsque je ne recoit rien.
Il peut arriver que je ne recoivent rien (applis distant qui plante ... ).
Le probleme c'est que je continue à attendre.
 
Je voudrais donc attendre que un certain temps.
 
Je ne sais pas vraiment comment faire ... ?

Reply

Marsh Posté le 24-12-2004 à 16:46:07   

Reply

Marsh Posté le 24-12-2004 à 16:56:14    

il faut utiliser la fonction select
 
voila je te donne une methode qui utilise la fonction select:
 

Code :
  1. short module::recv_message(SOCKET sock,sending_Struct &recv_struc)
  2. {
  3. if (int err=recv (sock,(char *) &recv_struc,524,0)==-1)
  4.    {   this->Gere_err_recv(err,sock);
  5.      
  6.    cout <<  "Error  Socket_error on recv data  <!> "<<endl;//throw __exeption( "Error  Socket_error on recv data  <!> " );
  7.         return -1;
  8.    }
  9. else
  10. return 0 ;
  11. }
  12. }
  13. int module::select_recv()
  14. {
  15.   this->threads_pseudo.create_thread(&thread_pseudo_envoi);
  16.   timeval waitTime;
  17.   waitTime.tv_sec = 0;// on met le timed ou t du select a 0
  18.   waitTime.tv_usec = 0;
  19.   for (;;)
  20.       {
  21.         Sleep(10);
  22.   boost::mutex::scoped_lock scoped_lock(ServerManager::GetInstance().mutex);
  23.   FD_SET pollingSet = this->masterSet;// copy dans un set temporaire
  24.        
  25.                 if (pollingSet.fd_count == 0)
  26.                            continue; //si ya reien dans le set on revien au debut
  27.        int result = select(pollingSet.fd_count, &pollingSet, NULL, NULL, &waitTime);
  28.                         if (result == 0)
  29.               continue; //po de socket en lecture on revient au debut de la boucle
  30.        if (result == SOCKET_ERROR)
  31.           {
  32.            printf("Error sur le select()\n" );
  33.    continue;
  34.            }
  35. //-----------------a partir de la on parcour le set pour faire ce quez l'on veut sur celuit ci
  36. for (unsigned int i = 0; i < pollingSet.fd_count; i++)
  37.     {
  38.        unsigned int clientSocket = pollingSet.fd_array[i];
  39.        string msg;
  40.        sending_Struct struc_echange;//= new sending_Struct;
  41.  
  42.    if (this->recv_message(clientSocket,struc_echange)==SOCKET_ERROR)
  43.                       continue;   
  44.    cout <<" message resu:"<<struc_echange.message<<endl;
  45.  
  46.              for (unsigned int o = 0; o < WRITE.fd_count ;o++)
  47.                {
  48.     
  49.       cout <<" ENVOYER sur le socket : ="<<this->WRITE.fd_array[o]<<endl;
  50.      
  51.       this->send_message(this->WRITE.fd_array[o],struc_echange);
  52.                  
  53.                
  54.      }//fin du for  
  55.          }//fin du for de parcour de socket
  56.      }//fin du for infini
  57. return 0;
  58. }


Message édité par tck59 le 24-12-2004 à 17:05:38
Reply

Marsh Posté le 24-12-2004 à 19:58:17    

ok j'ai compris et j'ai même réussi à mettre la solution en place ;)
 
 
A present j'ai un autre pb.
J'ai un connexion qui ne necessite pas qu'il y ai forcement de transfert, on peut etre connecté au serveur sans rien faire.
 
Seulement si le client se ferme mal le serveur ne sait pas qu'il n'ai plus là.
 
J'aurais une solution qui serait de pinguer toutes les x minutes les clients.
Le ping se ferait avec l'envoie d'un msg et d'une reponse de la part du client (là il y aurait un timeout)
 
2 questions:
- Y a t'il un autre moyen de savoir si le client n'est pas deco?
- Y aurait 'il une fonction spéciale pour le ping qui serait mieux que l'envoie d'un simple message?

Reply

Marsh Posté le 24-12-2004 à 21:15:44    

Le PING ne permet pas de surveiller une connexion TCP. Le PING est du niveau réseau tandis que la connexion TCP est du niveau transport.
 
SELECT te permet de surveiller les evenements en émission, réception et connexion/déconnexion. Interesses toi à la documentation de cette fonction, tu devrais trouver ce que tu cherches.


Message édité par xterminhate le 24-12-2004 à 21:16:11

---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 24-12-2004 à 23:42:06    

quand je parlais de ping c'était une image, je ne pensais pas à la vrai fonction.
 
Je regarderais avec la fonction select
 
merci

Reply

Marsh Posté le 25-12-2004 à 11:27:19    

Essaye peut etre avec le keepalive de TCP : avec setsockopt, active SO_KEEPALIVE. Le probleme c'est que par defaut un message est envoye toutes les deux heures.
 
Pour changer ca (par ex. 30 secondes) sous windows, il faut ajouter une clef dans la base de registre (http://support.microsoft.com/kb/q102973/)
 
System Key: [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters]
KeepAliveTime REG_DWORD 0x006DDD00 (30000)  
KeepAliveInterval REG_DWORD 0x000003e8 (1000)
 
et sous Linux il suffit de faire :
 echo "30" > /proc/sys/net/ipv4/tcp_keepalive_time
 
J'ai verifie que ca marchait sur W2K, il ne faut pas oublier de rebooter apres avoir change la registry.


Message édité par hoty le 27-12-2004 à 15:28:15

---------------
http://www.ikimegon.com/
Reply

Sujets relatifs:

Leave a Replay

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