WSAEventSelect et ioctlsocket

cs_Xentor609 Messages postés 258 Date d'inscription jeudi 20 mars 2003 Statut Membre Dernière intervention 16 août 2004 - 30 août 2003 à 16:12
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 - 5 sept. 2003 à 20:57
salut,
J'utilise WSAEventSelect pour savoir à quel moment un client se connecte et à quel moment il se déconnecte. Mon problème est que recv devient non-bloquant. Alors j'utilise
ioctlsocket mais elle me renvoie tout le temps -1.
Pourquoi? Comment rendre recv bloquant?
D'avance merci!
Bye,Xentor609

14 réponses

cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
30 août 2003 à 16:28
Salut,
WSAAsyncSelect et WSAEventSelect ne s'utilisent qu'avec les sockets non-bloquants.
Puisque tu utilises les events pour savoir quand ton client se connecte, pourquoi n'utilise tu pas un event pour savoir quand il t'envois quelque chose ?
0
cs_Xentor609 Messages postés 258 Date d'inscription jeudi 20 mars 2003 Statut Membre Dernière intervention 16 août 2004
30 août 2003 à 16:44
salut,
oui je sais que je pourrais savoir à quel moment le client a envoyé un message, mais dans mon programme, j'utilise recv dans des cas un peu particulier (je sais c un peu bizarre mais je sais po vraiment comment mieux t'expliquer).
Donc, si j'utilise WSAEventSelect, je ne peux pas utiliser les sockets en mode bloquant? C'est ça?
Merci d'éclairer ma lanterne!
Bye,Xentor609
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
30 août 2003 à 16:50
Salut,
C'est ca.
Dans quels cas bizzares utilise tu recv() ?
0
cs_Xentor609 Messages postés 258 Date d'inscription jeudi 20 mars 2003 Statut Membre Dernière intervention 16 août 2004
31 août 2003 à 13:54
C'est assez complique a expliquer, mais tout ce que je souhaiterai c'est de savoir quand est-ce qu'un client se deconnecte(en mode bloquant)?
Bye,Xentor609
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
31 août 2003 à 14:38
Salut,
En mode bloquant, quand recv() retourne 0 ou -1.
Tu peux savoir exactement ce qui s'est passé en appellant WSAGetLastError(). Si apres un recv() qui retourne -1, WSAGetLastError() retourne WSAENOTCONN, c'est que la connexion a été fermée.

Sinon, je crois que tu peux aussi utiliser le modele select().
0
cs_Xentor609 Messages postés 258 Date d'inscription jeudi 20 mars 2003 Statut Membre Dernière intervention 16 août 2004
31 août 2003 à 15:47
salut,
Tout d'abord merci aardman pour les réponses!
Est-ce qu'il y aurait une possibilité de savoir si un client est déconnecté ou pas, autre que recv et select?
Un genre de "bool IsConnected(SOCKET s)" ?
Le problème est que le serveur ne fait pas de recv en "temps normal", c'est même le client qui le fait, et attend un ordre envoyé par le serveur. Ce qui fait que l'utilisateur (c'est le serveur) va savoir qu'un client est déconnecté au moment même où il va envoyer un ordre au client.
Il y a la "solution banale", c'est-à-dire que le serveur envoye, tous les 5 sec par exemple, un "t'es là?" et le client lui répond par "oui" et si le client est déconnecté, recv va retourner 0 ou -1.
Bye,Xentor609
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
31 août 2003 à 16:15
Salut,
Ptet en faisant un connect() avec un autre socket mais avant les meme caracteristiques que celui que tu utilises dans ton programme(proto port et ip).
Si le socket est deja connecté, connect() retournera -1 et WSAGetLastError(..) retournera WSAEADDRINUSE.

je l'ai jamais fait mais je pense que ca marche.
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
31 août 2003 à 16:52
Salut,
Je viens de tester, en fait WSAGetLastError() retourne WSAEISCONN si le socket est deja connecté.
Ca donne:

BOOL IsConnected(SOCKET s)
{
if(connect(s,(sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR){
if(WSAGetLastError() == WSAEISCONN) return TRUE;
else return FALSE;}
else closesocket(s);
return FALSE;
}
0
cs_Xentor609 Messages postés 258 Date d'inscription jeudi 20 mars 2003 Statut Membre Dernière intervention 16 août 2004
31 août 2003 à 20:01
salut,
J'avais déjà pensé à un truc de ce genre. Moi j'utilisais getpeername je crois, mais le problème c'est qu'il me renvoyait 0, même quand le client était déconnecté.
Là, c'est à peu près pareil, c'est-à-dire que connect renvoie bien SOCKET_ERROR mais WSAGetLastError() renvoie tout le temps WSAEISCONN, même si le client est déconnecté.
Une idée?
Bye,Xentor609
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
31 août 2003 à 20:42
Salut,
2eme essai:
Le bidouillage avec connect() ne marche effectivement pas, on essaye avec select(..) alors.

BOOL IsConnected(SOCKET s, DWORD ms)
{
fd_set fdread;
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 1000*ms;
FD_ZERO(&fdread);
FD_SET(s, &fdread);
select(0, &fdread, 0, 0, &timeout);
if(FD_ISSET(s, &fdread)) return FALSE;
else return TRUE;
}

cette fonction est bloquante, le 2eme argument est le nbre de milliseconde avant qu'elle retourne (timeout).
Essaye voir si ca marche avec ca.
0
cs_Xentor609 Messages postés 258 Date d'inscription jeudi 20 mars 2003 Statut Membre Dernière intervention 16 août 2004
1 sept. 2003 à 20:15
salut,
Avec le select(...), j'ai déjà un meilleur résultat.
Mais il y a juste un détail qui me gêne : imaginons que le client envoye une chaine mais je n'ai pas fait de recv avant, et bien IsConnected me renvoye FALSE.
Il y a certainement une solution pour contourner ce problème, mais là, je suis à court d'idée.
Bye,Xentor609
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
1 sept. 2003 à 20:31
Salut,
Dans ce cas on teste le nbre d'octets qui attendent d'etre lus, si 0 ton client est bien déco.

BOOL IsConnected(SOCKET s, DWORD ms)
{
fd_set fdread;
timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 1000*ms;
DWORD bytepending = 0;
FD_ZERO(&fdread);
FD_SET(s, &fdread);
select(0, &fdread, 0, 0, &timeout);
if(FD_ISSET(s, &fdread)){
ioctlsocket(s, FIONREAD, &bytepending);
if(!bytepending) return FALSE;
else return TRUE;}
else return TRUE;
}

J'ai pas testé vu que je dois aller manger.
Dis moi si ca marche.
0
cs_Xentor609 Messages postés 258 Date d'inscription jeudi 20 mars 2003 Statut Membre Dernière intervention 16 août 2004
5 sept. 2003 à 20:47
salut,
Excellente ton idée, elle marche à merveille!
Merci pour tout aardman !
Bye,Xentor609
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
5 sept. 2003 à 20:57
Salut,
Cool.
Garde quand meme a l'esprit que c'est du bricolage comparé aux modeles EventSelect et AsyncSelect qui eux sont vraiment fait pour ce genre de manip.
0
Rejoignez-nous