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 :

Problème communication sockets serveur mutli-client


Sujet :

Réseau C

  1. #1
    Membre Expert
    Avatar de muad'dib
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2003
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2003
    Messages : 1 013
    Par défaut Problème communication sockets serveur mutli-client
    Bonjour à tous,

    Je réalise actuellement un serveur recevant plusieurs clients. Pour chaque client se connectant, je realise un accept() suivi d'un fork() afin que le processus enfant s'occupe du traitement des données recues par le client et que le processus parent puisse continuer l'écoute des nouvelles connexions entrantes.

    Jusque là rien que du très classique. Seulement je suis confronté à un problème, surement très connu, mais que je ne connais pas, aussi je vais tenter de vous l'expliquer:
    Je connecte 3 clients, les uns à la suite des autres. Nommons les A B C. Lorsqu'un client se connecte, le serveur doit alerter tous les clients déja connectés de l'arrivée du nouvel utilisateur. Idem pour une déconnexion:
    A se connecte: il est le premier, donc personne à alerter.
    B se connecte: le processus fils s'occupant du client B envoie une trame à A l'informant de la connexion de B.
    C se connecte: le processus fils s'occupant du client C envoie une trame à A et B les informant de la connexion de C.

    Jusqu'ici tout va bien ! Les différents clients connectés ainsi que leur descripteurs de fichiers sont stockés dans un segment de mémoire partagée, ce qui permet à tous les processus de connaitre en permanence quels sont les clients connectés.

    Les choses se compliquent lorsque je veux alerter les utilisateurs A et C de la déconnexion de B:
    B se déconnecte, le processus s'occupant de B envoie au descripteur de socket de A l'information de déconnexion -> OK, en revanche, le processus s'occupant de B envoie au descripteur de socket de C l'information de déconnexion -> KO et je me retrouve avec une erreur:
    send: Socket operation on non-socket
    Dans mon code, cela se traduit ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	for (i = 0; i < MAX_CLIENTS; i++) {
    		if (cl->sockfd > 0) {
    			printf("Alerting to socket %d - pid = %d\n", cl->sockfd, getpid());
    			if (send(cl->sockfd, data, strlen(data), 0) == -1) {
    				perror("send");
    			}
    		}
    		cl += sizeof(client);
    	}
    Où la variable cl correspond au pointeur sur les clients stockée en mémoire partagée.
    Je précise que la déconnexion du client n'est pas réelle, il s'agit juste d'une désautentification, la socket reste toujours connectée.

    J'ai l'impression que la méthode accept ne replique pas les descripteurs de sockets ouverts dans les processus enfants, me trompe-je ? Comment puis-je solutionner mon problème?

  2. #2
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Ceci n'est pas logique :
    cl est un pointeur donc on fait

    Le compilateur C fera le reste pour que cela pointe sur la prochaine entrée.

    Jc

  3. #3
    Membre Expert
    Avatar de muad'dib
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2003
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2003
    Messages : 1 013
    Par défaut
    Ah super merci je savais pas je vais essayer

    [EDIT] A marche po ... je met tout mon bout de code :
    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
    int alert_everyone(conn_alert_weave h_conn_alert) {
    	int i;
    	client *cl;
    	char data[256] = {0};
     
    	cl = (client*)shm_connected_clis;
     
    	sprintf(data, "%c%c%s", h_conn_alert.code, h_conn_alert.operation, h_conn_alert.login);
    	for (i = 0; i < MAX_CLIENTS; i++) {
    		if (cl->sockfd > 0 && cl->sockfd != h_conn_alert.sockfd) {
    			printf("Alerting to socket %d - pid = %d\n", cl->sockfd, getpid());
    			if (send(cl->sockfd, data, strlen(data), 0) == -1) {
    				perror("send");
    			}
    		}
    		cl++; //= sizeof(client);
    	}
     
    	return 0;
    }

  4. #4
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    euh.. Comme tu boucles en continu, il faudrait peut-être juste tester que tu ne prends pas le numéro en cours non ?

    Si c'est en mémoire partagée comme tu as l'air de le suggérer, les numéros sont stockés dans l'ordre de création, donc A, B, C.

    Quand ensuite dans B tu fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    	for (i = 0; i < MAX_CLIENTS; i++) {
    Comment c'est passé la déconnection ? est-ce que ton numéro de socket est déjà retiré de la liste ou non ? si oui, ton erreur est normale....

    ça me semble une mauvaise approche de faire comme ça...
    Parce que si de l'extérieur tu fais un KILL sur B, tu ne passeras pas par ta routine. De la même mnaière tu n'y passeras pas si il y a cordump, socket gelé, etc..

    J'aurais plutot fait un truc du genre :

    • chaque fois qu'un client est créé, il demande au serveur les autres clients, et les mets dans un tableau.
    • Chaque client a aussi une routine de signalisation en cas d'interruption de communication avec le serveur (quit sans bye)
    • Le serveur, quant à lui, garde l'ensemble en mémoire. Et il a une routine de vérification de connection pour chacun des clients, plus une routine de signalisation en cas d'interruption d'un des clients.
    • Quand un des clients quitte (volontairement ou non), le serveur passe à travers la liste des clients, envoie le message que le client no x a quitté, puis chacun remet à jour sa liste...

  5. #5
    Membre Expert
    Avatar de muad'dib
    Homme Profil pro
    Développeur Java
    Inscrit en
    Janvier 2003
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2003
    Messages : 1 013
    Par défaut
    Finalement, après concertation avec mon maitre de stage, j'ai utilisé une technique similaire à la tienne souviron. C'est à dire que chaque processus responsable de chaque client va comparer regulierement en mémoire partagée les clients connectés avec ceux de sa mémoire locale. S'il y a une différence, alors j'indique au processus du client d'alerter le client en question !!!!

    Merci pour ton aide en tout cas

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    de rien ..

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 28/03/2010, 18h53
  2. Liste chainée, sockets, serveur multi clients.
    Par jbarreau-mainson dans le forum Réseau
    Réponses: 4
    Dernier message: 01/05/2009, 12h15
  3. applet socket serveur + connexions clientes
    Par wilv8 dans le forum Applets
    Réponses: 2
    Dernier message: 30/10/2008, 10h04
  4. [reseaux] Communication socket/serveur - ne fonctionne plus !
    Par _jfi_ dans le forum Programmation et administration système
    Réponses: 11
    Dernier message: 17/11/2006, 14h46
  5. Socket serveur et client
    Par StreamEarth dans le forum Entrée/Sortie
    Réponses: 8
    Dernier message: 21/08/2006, 16h00

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