begin process at 2012 05 29 06:37:44
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Archive C/C++

 > 

Archives

 > 

Réseau / Internet

 > 

Evènement sur un socket client


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

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

Membre Club
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

Membre Club
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

Membre Club
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.

1 2

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


Nos sponsors


Sondage...

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,030 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales