Accueil > Forum > > > > Evènement sur un socket client
Evènement sur un socket client
vendredi 25 juillet 2003 à 12:25:49 |
Evènement sur un socket client

darsh99
|
J'aimerais savoir si la méthode utilisée par BlackGoddess pour son serveur (http://www.cppfrance.com/article.aspx?ID=1287) est récupérable pour gérer un client, particulièrement pour que le programme client détecte qu'il a perdu la connexion (soit par kick, soit dû à un pb réseau). J'ai essayé avec fd_close mais ça ne marche pas (le serveur fait un closesocket() sur le socket du client). J'avais réussi à détecter la perte du serveur avec recv(), mais je dois faire ça autrement. Je voulais que les requètes/réponses au serveur se fassent de façon pouctuelle et séquentielle, tout en faisant détecter la perte de connexion par une thread mais à y réfléchir ça risque de poser un problème entre la thread qui détecterait le conn lost et les recv séquentiels qui peuvent aussi détecter ce conn lost. Vais-je devoir éliminer la thread ? Arf et à y penser le serveur doit envoyer de temps en temps des ordres aux clients, ce qui parasiterait mes recv séquentiels... un vrai casse tête, aller je vais manger ça me permettra peut-être de trouver une solution, si quelqu'un en a une, qu'il n'hésite pas à me répondre :). Merci.
|
|
vendredi 25 juillet 2003 à 14:12:48 |
Re : Evènement sur un socket client

aardman
|
Salut, Je comprend pas ton probleme. Si ton serveur fait closesocket sur le socket d'un client alors le client recevra FD_CLOSE (quand ca marche ca fait ca). Elimine ta technique avec le thraed, FD_CLOSE marche nickel.
------------------------------- Réponse au message : -------------------------------
> J'aimerais savoir si la méthode utilisée par BlackGoddess pour son serveur (http://www.cppfrance.com/article.aspx?ID=1287) est récupérable pour gérer un client, particulièrement pour que le programme client détecte qu'il a perdu la connexion (soit par kick, soit dû à un pb réseau). > > J'ai essayé avec fd_close mais ça ne marche pas (le serveur fait un closesocket() sur le socket du client). > > J'avais réussi à détecter la perte du serveur avec recv(), mais je dois faire ça autrement. > Je voulais que les requètes/réponses au serveur se fassent de façon pouctuelle et séquentielle, tout en faisant détecter la perte de connexion par une thread mais à y réfléchir ça risque de poser un problème entre la thread qui détecterait le conn lost et les recv séquentiels qui peuvent aussi détecter ce conn lost. > Vais-je devoir éliminer la thread ? > > Arf et à y penser le serveur doit envoyer de temps en temps des ordres aux clients, ce qui parasiterait mes recv séquentiels... un vrai casse tête, aller je vais manger ça me permettra peut-être de trouver une solution, si quelqu'un en a une, qu'il n'hésite pas à me répondre :). > > Merci.
|
|
vendredi 25 juillet 2003 à 14:50:17 |
Re : Evènement sur un socket client

darsh99
|
En fait j'ai expliqué des trucs qui sont hors de mon problème, pour simplifier, je n'arrive pas à récupérer l'évènement FD_CLOSE, pourtant ce n'est pas faute de faire pareil que pour le serveur.
Je fais mon WSA create event juste avant de connecter le client au serveur (aucune erreur générée) : this->h_ConnexionRompue = WSACreateEvent(); WSAEventSelect(this->sk_Serveur, this->h_ConnexionRompue, FD_CLOSE); // Associer l'évènement FD_CLOSE du socket à he_Accept
puis je fais mon WSA wait for multiple events dans ma thread :
WaitRes = WSAWaitForMultipleEvents(cbTabEvents, TabEvents, FALSE, WSA_INFINITE, FALSE);
Mais lorsque le serveur fait le closesocket() (qui ne renvoie pas d'erreur), la thread du client ne bronche pas.
L'évènement se crée bien, la connexion se fait bien, le serveur reçoit bien le fd_close qd le client se déconnecte, mais qd le serveur kick tout le monde ça ne génère rien chez le client :/
------------------------------- Réponse au message : -------------------------------
> Salut, > Je comprend pas ton probleme. > Si ton serveur fait closesocket sur le socket d'un client alors le client recevra FD_CLOSE (quand ca marche ca fait ca). > Elimine ta technique avec le thread, FD_CLOSE marche nickel.
|
|
vendredi 25 juillet 2003 à 15:17:58 |
Re : Evènement sur un socket client

aardman
|
Salut, J'avais pas compris que tu utilisais WSAEventSelect désolé (perso j'utilise WSAAsyncSelect car pas de thread). Faudrais que tu poste ton code plutot que des copies de celui de BlackGoddess. he_Accept et TabEvents sont definis nulle part dans ton bout de code.
Moi je ferai:
WSAEVENT EventClose = WSACreateEvent(); WSAEventSelect( LeSocket, EventClose, FD_CLOSE);
// ...
WSAWaitForMultipleEvents( 1, EventClose, FALSE, WSA_INFINITE, FALSE);
------------------------------- Réponse au message : -------------------------------
> En fait j'ai expliqué des trucs qui sont hors de mon problème, pour simplifier, je n'arrive pas à récupérer l'évènement FD_CLOSE, pourtant ce n'est pas faute de faire pareil que pour le serveur. > > Je fais mon WSA create event juste avant de connecter le client au serveur (aucune erreur générée) : > this->h_ConnexionRompue = WSACreateEvent(); > WSAEventSelect(this->sk_Serveur, this->h_ConnexionRompue, FD_CLOSE); // Associer l'évènement FD_CLOSE du socket à he_Accept > > puis je fais mon WSA wait for multiple events dans ma thread : > > WaitRes = WSAWaitForMultipleEvents(cbTabEvents, TabEvents, FALSE, WSA_INFINITE, FALSE); > > Mais lorsque le serveur fait le closesocket() (qui ne renvoie pas d'erreur), la thread du client ne bronche pas. > > L'évènement se crée bien, la connexion se fait bien, le serveur reçoit bien le fd_close qd le client se déconnecte, mais qd le serveur kick tout le monde ça ne génère rien chez le client :/ > > ------------------------------- > Réponse au message : > ------------------------------- > > > Salut, > > Je comprend pas ton probleme. > > Si ton serveur fait closesocket sur le socket d'un client alors le client recevra FD_CLOSE (quand ca marche ca fait ca). > > Elimine ta technique avec le thread, FD_CLOSE marche nickel.
|
|
vendredi 25 juillet 2003 à 15:53:27 |
Re : Evènement sur un socket client

darsh99
|
> J'avais pas compris que tu utilisais WSAEventSelect désolé (perso j'utilise WSAAsyncSelect car pas de thread).
C'est-à-dire que je n'ai pas changé de méthode, celle utilisée par BG me convenait parfaitement (pour mon serveur).
> Faudrais que tu poste ton code plutot que des copies de celui de BlackGoddess. he_Accept et TabEvents sont definis nulle part dans ton bout de code.
Les copies viennent de mon code, je ne me suis pas amusé à renommer les variables temporaires telles que le tableau et sa taille, d'où le fait que la 3ième ligne que j'ai mise soit strictement identique au code de BG. Par contre comme je suis sur le client j'ai fait sauter le he_Accept et les he_clients, mon tableau fait seulement 2 events actuellement (le 2nd étant l'event pour fermer la thread).
Je n'ai pas mis le code parce qu'il est long, je vais essayer de mettre ça dans un message suivant celui-ci.
En regardant avec QuickWatch je me suis aperçu qu'en sortant de la thread ma liste de clients (côté serveur donc) perd des infos (les infos en char*, à savoir l'ip et le nom de machine), c'est un autre pb pour sûr mais le nom réseau de machine sous Windows est limité à combien de caractères ?
> WSAEVENT EventClose = WSACreateEvent(); > WSAEventSelect(LeSocket, EventClose, FD_CLOSE); > > // ... > > WSAWaitForMultipleEvents( 1, EventClose, FALSE, WSA_INFINITE, FALSE);
erf, le problème c'est qu'il y a le second évènement à gérer (pour quitter la thread) (toujours avec la méthode BG).
|
|
vendredi 25 juillet 2003 à 16:03:06 |
Re : Evènement sur un socket client

aardman
|
Salut, Essaye deja de faire fonctionner un event FD_CLOSE comme tu le souhaites avant d'essayer d'en gerer plusieurs.
Apres quand tu aura reussi, tu pourra mettre tout les events dans une tableau et passer le tableau en 2eme argument a WSAWaitForMultipleEvents (comme le fait BG).
Pour le probleme du nom reseau dans windows, désolé j'en ai aucune idée.
------------------------------- Réponse au message : -------------------------------
> > J'avais pas compris que tu utilisais WSAEventSelect désolé (perso j'utilise WSAAsyncSelect car pas de thread). > > C'est-à-dire que je n'ai pas changé de méthode, celle utilisée par BG me convenait parfaitement (pour mon serveur). > > > Faudrais que tu poste ton code plutot que des copies de celui de BlackGoddess. he_Accept et TabEvents sont definis nulle part dans ton bout de code. > > Les copies viennent de mon code, je ne me suis pas amusé à renommer les variables temporaires telles que le tableau et sa taille, d'où le fait que la 3ième ligne que j'ai mise soit strictement identique au code de BG. Par contre comme je suis sur le client j'ai fait sauter le he_Accept et les he_clients, mon tableau fait seulement 2 events actuellement (le 2nd étant l'event pour fermer la thread). > > Je n'ai pas mis le code parce qu'il est long, je vais essayer de mettre ça dans un message suivant celui-ci. > > En regardant avec QuickWatch je me suis aperçu qu'en sortant de la thread ma liste de clients (côté serveur donc) perd des infos (les infos en char*, à savoir l'ip et le nom de machine), c'est un autre pb pour sûr mais le nom réseau de machine sous Windows est limité à combien de caractères ? > > > WSAEVENT EventClose = WSACreateEvent(); > > WSAEventSelect(LeSocket, EventClose, FD_CLOSE); > > > > // ... > > > > WSAWaitForMultipleEvents( 1, EventClose, FALSE, WSA_INFINITE, FALSE); > > erf, le problème c'est qu'il y a le second évènement à gérer (pour quitter la thread) (toujours avec la méthode BG).
|
|
vendredi 25 juillet 2003 à 16:04:16 |
Re : Evènement sur un socket client

darsh99
|
Voilà le code côté client, je rechigne à mettre beaucoup de code parce qu'en général ça rebute.
// Ma fonction qui connecte le client au serveur bool CNetworkClient::ConnecterClient(char *ServeurIP, int ServeurPort) { this->h_GererClient = NULL;
// Initialisation des évènements this->h_DeconnecterClient = CreateEvent(NULL, FALSE, FALSE, NULL); this->h_ConnexionRompue = WSACreateEvent(); WSAEventSelect(this->sk_Serveur, this->h_ConnexionRompue, FD_CLOSE);
this->c_ServeurIP = ServeurIP; this->i_ServeurPort = ServeurPort;
// SI le client est déjà démarré ALORS ne rien faire if ( this->dw_EtatClient == CLIENTETAT_CONNECTE ) return false; // SINON le démarrer // Initialiser le socket de communication avec le(s) serveur(s) SOCKADDR_IN sin; sin.sin_addr.s_addr = inet_addr(c_ServeurIP); sin.sin_family = AF_INET; sin.sin_port = htons(i_ServeurPort); this->sk_Serveur = socket(AF_INET,SOCK_STREAM,0); bind(this->sk_Serveur, (SOCKADDR *)&sin, sizeof(sin)); // Tant que l'on est pas connecté au serveur, tenter la connection while ( connect(this->sk_Serveur, (SOCKADDR *)&sin, sizeof(sin)) ) { if ( MessageBox(NULL, "Impossible d'etablir la connection.\n\nVoulez-vous réessayer ?", dWinMSG_Client_Title, MB_RETRYCANCEL) == IDCANCEL) return false; } this->Afficher("Vous êtes connecté.");
this->GererClient(); this->SetEtatClient(CLIENTETAT_CONNECTE);
return true; }
// Ma thread de gestion du socket vers le serveur DWORD CNetworkClient::GERER_CLIENT(CNetworkClient *Client) { HANDLE* TabEvents; int cbTabEvents; DWORD WaitRes;
bool StopperClient = false; while(!StopperClient) { // Construction du tableau des évènements à gérer cbTabEvents = 2; TabEvents = new HANDLE[cbTabEvents];
TabEvents[0] = Client->h_DeconnecterClient; TabEvents[1] = Client->h_ConnexionRompue; WaitRes = WSAWaitForMultipleEvents(cbTabEvents, TabEvents, FALSE, WSA_INFINITE, FALSE);
delete[] TabEvents;
switch(WaitRes) { case WSA_WAIT_EVENT_0: { StopperClient = true; } break;
case WSA_WAIT_EVENT_0+1: { Client->Afficher("EVENEMENT : Connexion avec le serveur rompue."); } break; } // switch } // while
return 0; }
// A noter que je sais que toutes les erreurs ne sont ici pas gérées mais ça va venir (pour mon problème j'ai vérifié, aucune erreur générée)
|
|
vendredi 25 juillet 2003 à 16:28:41 |
Re : Evènement sur un socket client

darsh99
|
> WSAWaitForMultipleEvents( 1, EventClose, FALSE, WSA_INFINITE, FALSE);
Décidément :
" error C2664: 'WSAWaitForMultipleEvents' : cannot convert parameter 2 from 'void *' to 'void *const * ' "
|
|
vendredi 25 juillet 2003 à 16:31:39 |
Re : Evènement sur un socket client

darsh99
|
erf, je ne peux pas éditer mon message.
J'ai le cerveau en boulette, suffit bien sûr de mettre un & pour le EventClose.
Ca fait pareil, il ne détecte pas l'évènement.
|
|
vendredi 25 juillet 2003 à 17:23:37 |
Re : Evènement sur un socket client

darsh99
|
Bon et bien j'ai placé un send() sur le serveur et un recv() sur le client (juste après la création de la thread), la coupure serveur ainsi que le message envoyé par le send() sont détectés par le recv() mais pas par le WSAWaitxx de la thread.
J'ai trouvé une bouteille d'alcool dans le PC... j'en ai bu aussi, du coup je vais mettre un recv() dans ma thread et un case derrière, ça risque de m'handicaper mais je n'ai pas trop le choix, je ne peux pas me permettre de rester bloqué encore plus de temps.
|
|
Cette discussion est classée dans : serveur, client, détecter, socket, recv
Répondre à ce message
Sujets en rapport avec ce message
Tutorial - Socket, serveur, client BCPP + GUI [ par NyxArm ]
Bonjours tout le monde, je suis présentement en période d'appretissage du language CPP sur Borland(v.6). Maintenant que j'ai acquis quelque conna
Thread et socket besoin de conseil [ par kawito ]
Salut,je desire realiser un client/serveur TCPle probleme est que les fonctions accept et recv sont bloquante.donc cela bloque l'affichage etc...mon p
Probleme Architecture client Serveur Multithread [ par kawito ]
Bonjour,j'ai fais un client serveur TCP qui doit gerer n connexions(win32 c++) winsowk1.1.le serveur gere les connexions a travers un thread acceptqui
Fonctions send et recv [ par bubbless ]
Bonjour, Dans le cadre d'un projet, je réalise actuellement un système serveur / client, et je me trouve confronté à un probème : le serveur acc
recv recoit null [ par sena ]
bonjour,jai un client serveur TCP tout simple en TCP.mon client envoi des caractères au serveur et le serveur lui fait un accusé de reception en lui r
programmation socket sous linux [ par blazman34 ]
Bonjour à tous !!Voici mon probleme :Je suis en train de programmer une application client serveur sous linux, tout a bien marcher juska présent juska
problème socket sous windows [ par kod32 ]
Voici mon code : (winsock2.h)-----------------------------int main(){ /* inialisation */ WSADATA wsa; WSAStartup(MAKEWORD(2,0), &wsa); /*
client & server [ par Stormy ]
J'ai codé un serveur simple usant de TCP. Comme client j'utilise NetCat. Or, quand NetCat 'ferme', mon serveur ne détecte pas la clôture de la relatio
Qd un Socket reçoit une trame erronée ... [ par valoue ]
Bonjour,Je suis en train de développer una appli client serveur sous VC++, j'utilise des SOCKET.Le client et le serveur communiquent en s'envoyant des
Client/Serveur, encore..... [ par glubust ]
Je veux faire fonctionner une application client/serveur sous UNIX (client) et WINDOWS (serveur).Le programme client envoi une simple requête au serve
Livres en rapport
|
Derniers Blogs
JOYEUX ANNIVERSAIRE NIXJOYEUX ANNIVERSAIRE NIX par ebartsoft
Souhaitons un bon et joyeux anniversaire à notre hôte à tous, Nix.
Je ne le répéterais jamais assez mais sans lui rien ne serait possible. Il défit en permanence les lois de la gravité et comme il le dit si bien, si tu lui fais confiance ça devra...
Cliquez pour lire la suite de l'article par ebartsoft IMAGINE CUP 2012, MAKE A SIGN EN FINALEIMAGINE CUP 2012, MAKE A SIGN EN FINALE par junarnoalg
Voilà qui est fait, la nouvelle est officielle ! L'équipe belge "Make a Sign" va au pays des kangourous défendre son projet dans la catégorie Software Design. http://www.imaginecup.com/CompetitionsContent/Competition/WorldwideFinalists.aspx V...
Cliquez pour lire la suite de l'article par junarnoalg KINECT 1.5 IS OUT !KINECT 1.5 IS OUT ! par Vko
La version 1.5 du Kinect For Microsoft vient tout juste de sortir ! Plein de nouveautés: Tracking de squelette en Near Mode Détection en position assise Détection faciale avec un SDK dédié Documentation et des guideline (enfin) Un out...
Cliquez pour lire la suite de l'article par Vko LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) par richardc
Mise à jour des Web API du 14 Mai
Réservez dès maintenant votre journée du 20 juin pour le Windows Azure Dev Camp 2012 à Paris
Mise à jour de Team Foundation Service
MechCommander 2 sur Windows 8
Entity Framework 5 Release Candidate e...
Cliquez pour lire la suite de l'article par richardc REACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITERREACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITER par Groc
Une mauvaise utilisation de rx lors de l'écriture d'une couche d'accès à des services peut conduire à des cas embarassants avec des erreurs mal gérées, des appels qui ne partent lorsqu'ils le devraient, et même des résultats incorrects . le tout nuis...
Cliquez pour lire la suite de l'article par Groc
Logiciels
sDEVIS-FACTURES vlPRO (8.1.0.3)SDEVIS-FACTURES VLPRO (8.1.0.3)sDEVIS-FACTURES vlPRO a été mis au point pour les particuliers, créateurs, entrepreneurs, artisa... Cliquez pour télécharger sDEVIS-FACTURES vlPRO 974 Application Server (12.2.4.6)974 APPLICATION SERVER (12.2.4.6)Développez de puissantes applications dans un environnement de 'cloud computing', clusterisé, séc... Cliquez pour télécharger 974 Application Server vPicture (1.4.2.1)VPICTURE (1.4.2.1)Avec vPicture, hébergez vos images facilement et rapidement.
vPicture est un utilitaire simple, ... Cliquez pour télécharger vPicture Easy-Planning (2.2.1.6)EASY-PLANNING (2.2.1.6)Easy-Planning permet de créer des plannings sous la représentation de diagrammes et est adapté au... Cliquez pour télécharger Easy-Planning COM-BACKUP (2.0)COM-BACKUP (2.0)
COM-BACKUP est un logiciel de sauvegarde qui permet de planifier les sauvegardes de vos dossiers ...
Cliquez pour télécharger COM-BACKUP
|