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:
Dans mon code, cela se traduit ainsi:send: Socket operation on non-socket
Où la variable cl correspond au pointeur sur les clients stockée en mémoire partagée.
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); }
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?
Partager