IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

Les subtilités d' epoll


Sujet :

Réseau C

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    ingenieur calcul haute performance
    Inscrit en
    Février 2013
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingenieur calcul haute performance
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2013
    Messages : 51
    Points : 35
    Points
    35
    Par défaut Les subtilités d' epoll
    Bonjour,

    Je suis actuellement entrain de programmer une application serveur TCP asynchrone:
    Je cherche a détecter une demande de connexion, l'établir puis la maintenir....
    Pour cela j'utilise l'appel système epoll qui permet d'attendre qu'un événement se produise sur un descripteur de fichier (en l'occurrence une liste de sockets).

    Le problème est que entre deux appels a epoll, il se produit parfois des événements sur les sockets connecté, du coup, lorsque l'on utilise epoll après le changement d'état , il n'est plus capable de détecter ce changement puisqu'il a déjà eu lieu...

    Ce phénomène est très embêtant pour mon application puisqu'il bloque tout, le serveur comme le client:
    Le serveur reste bloqué sur epoll.
    Le client attend une réponse du serveur il est donc aussi bloqué.

    Quelqu'un aurait il une idée pour détecter touts les changements d'états des descripteurs a surveiller?

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 372
    Points : 23 628
    Points
    23 628
    Par défaut
    Bonjour,

    Entre autres choses, epoll est capable de fonctionner en détection d'état OU en détections de transition d'états, c'est-à-dire des fronts (edges).

    Pourquoi utilises-tu un truc aussi sophistiqué pour faire de la bête gestion de connexions TCP ? Un simple select() ou même un poll() de première génération ne pourraient-ils pas suffire ?

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    ingenieur calcul haute performance
    Inscrit en
    Février 2013
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingenieur calcul haute performance
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2013
    Messages : 51
    Points : 35
    Points
    35
    Par défaut
    Salut Obsidian,

    Merci pour ta réponse.

    En fait j'ai essayé les deux types de détections et a chaque foi, j'obtiens un blocage, car dans les deux cas (si j'ai bien compris) si on a pas de transition, il n'y a pas de détection.
    (je suis a peu près sur de cela car j'ai fait un test avec des temps d'attente imposés de telle sorte que l'on ne puisse pas avoir un descripteur près en lecture avant de rentrer dans epoll_wait et, ça marche!!!!)


    Du coup, si des données arrivent sur une socket avant epoll_wait, il n'est pas capable de détecter l'arrivée de ces données..

    Je suis ouvert a plus d'explications car je suis totalement novice avec cet appel système.

    Pour info, j'utilise cet appel car c'est une application de load balancing qui peut avoir a gérer des milliers de connexions simultanés(donc pas de select déja car on est limités a 1024).

  4. #4
    Membre émérite
    Avatar de imperio
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2010
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2010
    Messages : 852
    Points : 2 298
    Points
    2 298
    Par défaut
    Qu'est-ce tu appelles une transition ? Dans le man de select il y a un très bon exemple expliquant comment faire avec un exemple. Je pense que tu as juste mal fait quelque chose car cette fonction ne sera bloquante que dans un seul cas :

    Tu n'as pas mis de timeout et tu n'as reçu aucun évènement sur les descripteurs de fichiers passés en paramètres.

    Je pense qu'en nous montrant ce que tu as déjà fait cela pourrait nous aider à t'orienter.

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    ingenieur calcul haute performance
    Inscrit en
    Février 2013
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingenieur calcul haute performance
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2013
    Messages : 51
    Points : 35
    Points
    35
    Par défaut
    Salut imperio,

    Donc voici les parties du code qui concernent epoll (je peut pas tout mettre car c'est assez énorme).
    Ce code est juste destiné a des tests pour l'instant.

    1) la fonction contenant epoll_wait (celle qui bloque justement)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    int wait_event(int epollfd)
    {
    	int n, i;
    	struct epoll_event events[64];
    	memset(events,0,sizeof(events));
    	n = epoll_wait(epollfd, events, 64, -1);
    	fprintf(stderr,"%i events\n\n",n);
    	for(i = 0; i < n; i++)
    	{
    		if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP))
    		{
    			fprintf(stderr, "epoll error\n");
    			close (events[i].data.fd);
    		}
    		else
    		{
    			return events[i].data.fd;
    		}
    	}
    	return -1;
    }
    2)La partie du code ou celle ci est appelée:donc après socket, setsockopt, bind....
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    unblock_sock(sock);
    if (listen(sock,backlog) < 0)
    {
    	perror("listen");
    	exit(EXIT_FAILURE);
    }
    event.data.fd = sock;
    event.events = EPOLLIN | EPOLLPRI | EPOLLHUP | EPOLLERR;
     
     
    epollfd = epoll_create(1);
    if (epoll_ctl (epollfd, EPOLL_CTL_ADD, sock, &event) == -1)
    {
    	perror("epoll_ctl in main");
    	exit(EXIT_FAILURE);
    }
     
    for(;;)
    {
    	sock_poll = wait_event(epollfd);
     
    	if (sock_poll == sock)
    	{
    		make_connection(sock,&sock_con,client_ip,&client_port);
    		client_auth(&sock_con);
    		event.data.fd = sock_con;
    		event.events = EPOLLIN | EPOLLPRI | EPOLLHUP | EPOLLERR;
    		epoll_ctl(epollfd, EPOLL_CTL_ADD, sock_con, &event);
    	}
    	else
    	{
    		sock_con = sock_poll;	
    		//là j'utilise la connexion tcp sur la socket sock_con
    	}
    }

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    ingenieur calcul haute performance
    Inscrit en
    Février 2013
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingenieur calcul haute performance
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2013
    Messages : 51
    Points : 35
    Points
    35
    Par défaut
    Merci encore pour vos réponses,

    Je viens de trouver le problème, et il n'apparaît pas dans le code.

    Je vais tout de même expliquer le bug au cas ou cela pourrait aider quelqu'un.

    Avant d'utiliser le multiplexage avec epoll, mon application établissait une connexion tcp par transmission de données.. En gros:
    -le client demande du travail sur une connexion tcp puis la ferme (le serveur ferme également du coup).
    -le client calcule..
    -le client envoie le résultat du calcul sur une connexion puis la ferme(le serveur ferme également du coup).
    etc...

    Ce mode est très pratique car il permet de synchroniser les échanges de données.
    Cependant il a un gros défaut: si trop de connexions sont crées par secondes, les client n'ont plus de port dynamique pour se connecter, du coup ils meurent..

    J'ai donc décidé de passer au multiplexage et de garder les connexion tcp actives.

    Du coup j'ai repris le code que j'avais écrit en modifiant que quelques parties.
    Mais j'ai oublié un petit détail, lorsque je transfère des données de longueur arbitraire, il faut d'abord transférer la taille des données que l'on envoie et, ne pas faire plus de read du coté ou l'on reçois que la taille des données que l'on envoie sinon on risque de lire des données supplémentaires destinées a une autre transmission.
    Ce phénomène ne peut pas se produire si on détruis les connections tcp a chaque transmissions.

    Le bug me concernant etais donc le suivant:

    Le client fait une demande au serveur et lui transmet des données calculées.
    Le serveur de son coté effectue des reads, sauf que le dernier read était trop grand (32768): donc je me retrouve a lire également le début de l'entête de la commande d'après.
    Le client lui a donc déjà envoyé sont entête pour la transmission suivante et attend la réponse du serveur or le serveur est bloqué sur epoll puisqu'il a déja reçu l'entete... (se faisant la confondant avec la fin des transmissions de la commande précédente).
    Le client est donc bloqué également.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Les subtilitées d' epoll suite
    Par dodo285 dans le forum Réseau
    Réponses: 3
    Dernier message: 05/06/2013, 10h38
  2. Obligatoire : lisez les règles du forum : MAJ 06/08/2010
    Par Anomaly dans le forum Mode d'emploi & aide aux nouveaux
    Réponses: 0
    Dernier message: 03/07/2008, 13h46
  3. Subtilité sur les combo box
    Par SuperWeight dans le forum MFC
    Réponses: 2
    Dernier message: 14/06/2007, 11h17
  4. Les subtilités de DOM
    Par Sly2k dans le forum Servlets/JSP
    Réponses: 7
    Dernier message: 18/05/2007, 10h42
  5. Subtilités sur les unions
    Par PsyKroPack dans le forum C
    Réponses: 4
    Dernier message: 26/01/2007, 10h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo