Socket, process et autre avec c++

Socket, process et autre avec c++ - C++ - Programmation

Marsh Posté le 27-08-2004 à 18:19:01    

Bonjour à tous,
 
Le c++, c'est bien mais ça devient vite compliqué quand on touche des domaines assez techniques (TCP-IP) et aussi quaud ce n'est pas nous qui avons écrit le programme  :pt1cable:  
 
Bref ! Voici un petit bout de code que je m'empresse de vous expliquez.
On a un systeme qui reçoit des messages ou des demandes de connexion qui viennent de plusieurs entrés, en l'occurence "de gescom" et d'une socket lsock. En gros, on lit sur ces deux sockets. Si un événement arrive (sur l'un ou l'autre), on lit en priorité sur Gescom puis sur lsock. S'il une connexion s'établit sur lsock, il construit un message et le renvoie à un autre systeme illico.
 

Code :
  1. lsock = bindandlisten();
  2.     signal(SIGHUP, trait_sighup);
  3.     signal(SIGINT, trait_sighup);
  4.     signal(SIGQUIT, trait_sighup);
  5.     signal(SIGILL, trait_sighup);
  6.     signal(SIGTRAP, trait_sighup);
  7.     signal(SIGABRT, trait_sighup);
  8. #ifndef LINUX
  9.     signal(SIGEMT, trait_sighup);
  10. #endif
  11.     signal(SIGFPE, trait_sighup);
  12.     signal(SIGBUS, trait_sighup);
  13.     signal(SIGSEGV, trait_sighup);
  14.     signal(SIGSYS, trait_sighup);
  15.     signal(SIGPIPE, trait_sighup);
  16.     signal(SIGXCPU, trait_sighup);
  17.     signal(SIGXFSZ, trait_sighup);
  18.     signal(SIGCHLD,trait_child);
  19.     signal(SIGALRM, SIG_IGN);
  20.     signal(SIGUSR1,trait_sig_usr1_accueil);
  21. struct pollfd pollfds[2];
  22. const int delai1 = 500;
  23. const int POLLGESCOMNUM = 0;
  24. const int POLLSOCKETNUM = 1;
  25. boucler = TRUE;
  26. for (;boucler;)
  27. {
  28.  testModifEnv_accueil(pmqgescom);
  29.  /* attendre les connections */
  30.  // Attendre soit un accès pipe soit une connexion sur le socket
  31.  // si connexion sur le socket détectée accept ne bloquera pas
  32.  pollfds[POLLGESCOMNUM].fd = pipe_accu2gescom[0];  // lecture sur pipe gescom
  33.  pollfds[POLLGESCOMNUM].events = POLLIN;
  34.  pollfds[POLLSOCKETNUM].fd = lsock;      // lecture sur le socket
  35.  pollfds[POLLSOCKETNUM].events = POLLIN;
  36.  int tmp_timer = delai1;
  37.  switch (poll(pollfds,(accept_connexion==TRUE)?2:1,tmp_timer))
  38.  {
  39.  case 0:
  40.   // timeout
  41.   // rien de particulier à faire a priori : boucler
  42.   // si code retour EINTR il y a eu un traitement de signal
  43.   break;
  44.  case 1: case 2:;
  45.   // POLLIN (1 ou 2 evt pollés)
  46.   // soit message de gescom soit connexion
  47.   // pollin sur message
  48.   // on traite en priorité les messages des sessions
  49.   // puis ceux du controleur de session
  50.   // et enfin ceux de l'accueil
  51.   if (pollfds[POLLGESCOMNUM].revents)
  52.   {
  53.    if (pollfds[POLLGESCOMNUM].revents & POLLIN)
  54.    {
  55.     // réception d'un message
  56.     if (pmqgescom.receive(msg1))
  57.     {
  58.      // si c'est le cas traiter le message
  59.      AccueilMessageRecu(msg1,pmqgescom,tsi,lsock);
  60.     }
  61.     else
  62.     {
  63.      klog.trace(9,"A116",ACCUEIL,'E',"AL_CANT_CONNECT_GESCOM : fin de l'accueil" );
  64.      boucler = FALSE;
  65.     }
  66.    }
  67.    else if (pollfds[POLLGESCOMNUM].revents & (POLLHUP|POLLNVAL|POLLERR))
  68.    {
  69.     klog.trace(9,"A117",ACCUEIL,'E',"AL_CANT_CONNECT_GESCOM : fin de l'accueil (probleme de communication avec Gescom)" );
  70.     boucler = FALSE;
  71.    }
  72.    else
  73.    {
  74.     // etat du polling inattendu
  75.    }
  76.   }
  77.   if (pollfds[POLLSOCKETNUM].revents)
  78.   {
  79.    if ((accept_connexion==TRUE) && (pollfds[POLLSOCKETNUM].revents & POLLIN))
  80.    {
  81.     klog.trace(300,"A118",ACCUEIL,'L',"Connexion Tcp/IP en cours" );
  82.     // connection sur le socket
  83.     caddrlen = sizeof(caddr);
  84.     memset(&caddr, '\0', sizeof(caddr));
  85. #ifndef LINUX
  86.     csock = accept(lsock,&caddr, &caddrlen);
  87. #else
  88.     csock = accept(lsock,&caddr, (unsigned int *)&caddrlen);
  89. #endif
  90.     
  91.                     if (csock < 0 SOCKET_ERROR  )
  92.     {
  93.      if (errno != EINTR)
  94.      {
  95.       // erreur sur le accept, tracer l'erreur
  96.       klog.trace(29,"A119",ACCUEIL,'W',"LOG_SESSION_REFUSED_SOCKET_ERROR ",errno);
  97.      }
  98.     }
  99.     else
  100.     {
  101.      // signaler la connection a Gescom
  102.      Framed_Ip_Address = (int)ntohl(((struct sockaddr_in*)&caddr)->sin_addr.s_addr);
  103.      msg1.mkTCP_SESSION_REQUEST(Framed_Ip_Address );
  104.      pmqgescom.send(msg1);
  105.      // sauvegarder le socket de connection (temporairement)
  106.      tsi.addSockInfo(Framed_Ip_Address,csock,&caddr,caddrlen);
  107.     }
  108.    }
  109.   }
  110.   break;


ça c'était avant!
 
Le problème maintenant, c'est qu'une fois qu'on a une connexion sur lsock, on doit recevoir des données avant de construire un message et de le renvoyer ( avant on servait juste de relai )et là ça devient plus compliqué sachant qu'on veut éviter au maximum les temps morts (ce qui était le cas avant). En gros, une fois la connexion établie avec csock, il faut écouter sur csock or si on le fait dans la foulée, ça risque de créer des temps morts.
 
 :ange:  
Bon je suis conscient de ne pas être très clair...
C'est pourquoi je me tiens à votre disposition s'il y a des bonnes âmes fan d'informatique qui veulent bien m'aider pour répondre à leur questions.


Message édité par cakeman le 30-08-2004 à 14:18:44
Reply

Marsh Posté le 27-08-2004 à 18:19:01   

Reply

Marsh Posté le 30-08-2004 à 10:48:28    

Est ce que qqun au moins pourrait me dire où trouver les infos concernant la librairie poll.h et signal.h ?

Reply

Marsh Posté le 30-08-2004 à 13:41:55    

Utilise les balises [cpp] pour ton code. Après, pour ton problème, c'est quoi un temps mort ? Explique en 2 lignes ton problème.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 30-08-2004 à 14:42:55    

Dsl pour les balises, je n'avais pas vu que ça existait.
 
En gros, on écoute deux systèmes (qu'on appellera système 1 et système 2 alias gescom)à la fois.
Le principe de base: on reçoit une demande du système 1 qu'on retransmets immédiatement au système 2.
Actuellement, on se met en écoute sur tous les ports et dès qu'on reçoit un signal (poll(pollfds,(accept_connexion==TRUE)?2:1,tmp_timer)), on traite en priorité les messages proveant de système 2. Si le signal arrive du système 1, on construit immédiatement le message à envoyer au système 2.
 

Code :
  1. pollfds[POLLGESCOMNUM].fd = pipe_accu2gescom[0];  // lecture sur pipe gescom
  2. pollfds[POLLGESCOMNUM].events = POLLIN;
  3. pollfds[POLLSOCKETNUM].fd = lsock;      // lecture sur le socket
  4. pollfds[POLLSOCKETNUM].events = POLLIN;


 
Seulement maintenant il y a une variante. A partir du moment où on reçoit un signal du sytème 1, il faut se mettre attente pour recevoir  d'autres données avant de faire suivre au système 2.
Avant on n'écoutait que sur deux canals (celui du système 1 et celui du système 2. Or maintenant, on devra écouter sur d'autres ports (n sur le système 1 et un sur le système 2). On met donc un timeout de 5 s sur les ports en écoute sur le système 1.
 
J'avoue que c'est assez délicat à expliquer donc n'hésitez pas à demander des précisions.
 

Reply

Marsh Posté le 31-08-2004 à 15:14:55    

Personne ne sait où je peux trouver  des renseigner sur la librairie "poll.h" et en particulier sur la fonction "poll" ?

Reply

Marsh Posté le 31-08-2004 à 16:16:55    

va voir dans le site www.guill.net

Reply

Sujets relatifs:

Leave a Replay

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