cakeman | 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 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 :
- lsock = bindandlisten();
- signal(SIGHUP, trait_sighup);
- signal(SIGINT, trait_sighup);
- signal(SIGQUIT, trait_sighup);
- signal(SIGILL, trait_sighup);
- signal(SIGTRAP, trait_sighup);
- signal(SIGABRT, trait_sighup);
- #ifndef LINUX
- signal(SIGEMT, trait_sighup);
- #endif
- signal(SIGFPE, trait_sighup);
- signal(SIGBUS, trait_sighup);
- signal(SIGSEGV, trait_sighup);
- signal(SIGSYS, trait_sighup);
- signal(SIGPIPE, trait_sighup);
- signal(SIGXCPU, trait_sighup);
- signal(SIGXFSZ, trait_sighup);
- signal(SIGCHLD,trait_child);
- signal(SIGALRM, SIG_IGN);
- signal(SIGUSR1,trait_sig_usr1_accueil);
- struct pollfd pollfds[2];
- const int delai1 = 500;
- const int POLLGESCOMNUM = 0;
- const int POLLSOCKETNUM = 1;
- boucler = TRUE;
- for (;boucler;)
- {
- testModifEnv_accueil(pmqgescom);
- /* attendre les connections */
- // Attendre soit un accès pipe soit une connexion sur le socket
- // si connexion sur le socket détectée accept ne bloquera pas
- pollfds[POLLGESCOMNUM].fd = pipe_accu2gescom[0]; // lecture sur pipe gescom
- pollfds[POLLGESCOMNUM].events = POLLIN;
- pollfds[POLLSOCKETNUM].fd = lsock; // lecture sur le socket
- pollfds[POLLSOCKETNUM].events = POLLIN;
- int tmp_timer = delai1;
- switch (poll(pollfds,(accept_connexion==TRUE)?2:1,tmp_timer))
- {
- case 0:
- // timeout
- // rien de particulier à faire a priori : boucler
- // si code retour EINTR il y a eu un traitement de signal
- break;
- case 1: case 2:;
- // POLLIN (1 ou 2 evt pollés)
- // soit message de gescom soit connexion
- // pollin sur message
- // on traite en priorité les messages des sessions
- // puis ceux du controleur de session
- // et enfin ceux de l'accueil
- if (pollfds[POLLGESCOMNUM].revents)
- {
- if (pollfds[POLLGESCOMNUM].revents & POLLIN)
- {
- // réception d'un message
- if (pmqgescom.receive(msg1))
- {
- // si c'est le cas traiter le message
- AccueilMessageRecu(msg1,pmqgescom,tsi,lsock);
- }
- else
- {
- klog.trace(9,"A116",ACCUEIL,'E',"AL_CANT_CONNECT_GESCOM : fin de l'accueil" );
- boucler = FALSE;
- }
- }
- else if (pollfds[POLLGESCOMNUM].revents & (POLLHUP|POLLNVAL|POLLERR))
- {
- klog.trace(9,"A117",ACCUEIL,'E',"AL_CANT_CONNECT_GESCOM : fin de l'accueil (probleme de communication avec Gescom)" );
- boucler = FALSE;
- }
- else
- {
- // etat du polling inattendu
- }
- }
- if (pollfds[POLLSOCKETNUM].revents)
- {
- if ((accept_connexion==TRUE) && (pollfds[POLLSOCKETNUM].revents & POLLIN))
- {
- klog.trace(300,"A118",ACCUEIL,'L',"Connexion Tcp/IP en cours" );
- // connection sur le socket
- caddrlen = sizeof(caddr);
- memset(&caddr, '\0', sizeof(caddr));
- #ifndef LINUX
- csock = accept(lsock,&caddr, &caddrlen);
- #else
- csock = accept(lsock,&caddr, (unsigned int *)&caddrlen);
- #endif
-
- if (csock < 0 SOCKET_ERROR )
- {
- if (errno != EINTR)
- {
- // erreur sur le accept, tracer l'erreur
- klog.trace(29,"A119",ACCUEIL,'W',"LOG_SESSION_REFUSED_SOCKET_ERROR ",errno);
- }
- }
- else
- {
- // signaler la connection a Gescom
- Framed_Ip_Address = (int)ntohl(((struct sockaddr_in*)&caddr)->sin_addr.s_addr);
- msg1.mkTCP_SESSION_REQUEST(Framed_Ip_Address );
- pmqgescom.send(msg1);
- // sauvegarder le socket de connection (temporairement)
- tsi.addSockInfo(Framed_Ip_Address,csock,&caddr,caddrlen);
- }
- }
- }
- 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.
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
|