Deconnection d'un client

cs_Xentor609 Messages postés 258 Date d'inscription jeudi 20 mars 2003 Statut Membre Dernière intervention 16 août 2004 - 28 juil. 2003 à 17:57
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 - 28 juil. 2003 à 23:52
Bonjour,
j'ai une appli client-serveur et je souhaiterai savoir lorsque'un
client est deconnecte.
Imaginons que le pc client redemarre, ou qu'il se deconnecte d'internet tout simplement.
Je voudrais donc connaitre quand le client se deconnecte,afin qu'il m'avertisse que celui-ci n'est plus la.
Kkun a une idee?
Bye,Xentor609

30 réponses

sebseb42 Messages postés 495 Date d'inscription dimanche 6 juillet 2003 Statut Membre Dernière intervention 9 novembre 2007 1
28 juil. 2003 à 21:32
si si, tres claire, mais tu va voir qu'on retombe sur nos pattes :)

generalement, un serveur est ecrit de la sorte (en tres gros)

while (1)
{
recv(...)
traitement(...);
}

dans traitement, tu fait tout ce que tu as a faire, par exemple, envoyer un fichier

imagine qu'un client te dit, "envoie moi truc.txt", le serveur le capte dans le recv, et par dans traitement, dans traitement tu envoie ton fichier "truc.txt" via (plusieurs) send

jusque la, tout va bien

admettons que ton client se deconnecte alors que tu lui envoie le fichier, au moment ou il va se deconnecter, ton send va te renvoyer -1 (ce qui ne veut pas forcement dire que ton client est mort) donc dans ce cas, tu dis que ton transfer a merder, tu as fini ton traitement, et tu quitte traitment....

c'est alors que tu reviend dans ta fonction d'avant, tu reboucle et la, tu retombe sur ton recv qui lui, te dira -1 :)
et la tu sais que ton client est mort... entre le send -1, return et recv -1, il se passera franchement pas enormement de temps, donc ton probleme est resolu :)

voila, hesite pas si tu as encore des questions :)
0
cs_Xentor609 Messages postés 258 Date d'inscription jeudi 20 mars 2003 Statut Membre Dernière intervention 16 août 2004
28 juil. 2003 à 21:38
Super, Merci j'y avais meme pensé, pourtant c'est très simple.
Bon ben on dira que mon probleme est resolu, je n'aurai qu'a le programmer demain matin.
Merci encore pour ton aide!
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
28 juil. 2003 à 21:41
merci pour la reponse,
Je te rassure je fais parfaitement bien la difference entre les socket bloquant/non bloquant, et les threads. J'ai du mal expliquer la relation entre ces 2 choses dans mon précédent post.

Un socket bloquant bloque, donc generalement on crée un thread qui s'occupe des receptions pour ne pas bloquer le thread principal (mais rien ne t'empeche d'utiliser les socket bloquant dans le thread principal... simplement pour gerer les send/recv c'est pas la joie).

Un socket non bloquant ne bloque pas, donc pas vraiment besoin d'un autre thread pour gerer les receptions puisqu'il ne bloque pas le thread principal.
J'espere que j'ai été plus clair que dans le post d'avant.

> En socket non-bloquant (donc sans thread) recv==-1
je sous entendais ce que je viens de redire au dessus :).

Enfin, en socket non bloquant, recv retourne toujours -1 sauf s'il est placé juste apres un event FD_READ. Donc recv==-1 ne se traduit pas forcément par une deco du client.
0
sebseb42 Messages postés 495 Date d'inscription dimanche 6 juillet 2003 Statut Membre Dernière intervention 9 novembre 2007 1
28 juil. 2003 à 21:55
de rien, c'est toujours un plaisir de pouvoir aider qqun :)
0

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

Posez votre question
sebseb42 Messages postés 495 Date d'inscription dimanche 6 juillet 2003 Statut Membre Dernière intervention 9 novembre 2007 1
28 juil. 2003 à 22:03
> Enfin, en socket non bloquant, recv retourne toujours -1
> sauf s'il est placé juste apres un event FD_READ. Donc
> recv==-1 ne se traduit pas forcément par une deco du
> client.

bon, je vois ce que tu veux dire, mais tu te trompe, en non bloquant, quand ton file-descriptor n'as rien recu, il renvoie tout simplement 0, et non pas -1, tu peux faire des tests si tu veux, tu verra bien par toi meme

et donc dans ce cas, -1 signifie que le client est mort...

ca fait 200 milles posts que je repete la meme chose, mais vous savez, vous pouvez poster encore si vous voulez, ca ne changera rien :)

-1 sera toujours equivalenet a une deconnection de la partie distante :)
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
28 juil. 2003 à 22:34
Salut,
j'ai fait un petit serveur pour tester, une simple dialogbox avec un bouton grisé par defaut.
Lorsqu'un client se connecte, le bouton deviens clickable et lorsqu'on clique dessus il appelle la fonction recv(). La valeur que retourne recv est affichée dans une MessageBox. Lorsque le client se deconnecte, le bouton redeviens grisé.

Alors je lance le prog, je fais un telnet dessus, le bouton deviens clickable, je clique dessus et la MessageBox affiche -1.
Et lorsque je ferme telnet, le bouton deviens grisé.
C'est un socket non bloquant, et recv retourne -1 alors que le client est toujours connecté.

#include <stdio.h>
#include <winsock2.h>
#include <windows.h>
#include "resource.h"
#pragma comment(lib, "ws2_32.lib")
#define WM_SOCKET 0x0401

SOCKET s;
SOCKET c;
sockaddr_in sin;
int Size = sizeof(sin);
int iReturnValue = 0;
HWND hButton;
char szBuf[256];
char szMsg[256];

BOOL CALLBACK AppDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
WSADATA wsa;
WSAStartup(MAKEWORD(2,0), &wsa);
DialogBox(hInstance, "MainDialog", 0, AppDlgProc);
return 0;
}

BOOL CALLBACK AppDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
hButton = GetDlgItem(hDlg, IDOK);
EnableWindow(hButton, FALSE);

s = socket(AF_INET, SOCK_STREAM, 0);
sin.sin_family = AF_INET;
sin.sin_port = htons(2003);
sin.sin_addr.S_un.S_addr = INADDR_ANY;
bind(s,(sockaddr *) &sin, Size);
listen(s, 5);
WSAAsyncSelect(s, hDlg, WM_SOCKET, FD_ACCEPT | FD_CLOSE);
return 0;
case WM_SOCKET:
if(LOWORD(lParam) == FD_ACCEPT)
{
c = accept(s,(sockaddr *) &sin, &Size);
EnableWindow(hButton, TRUE);
}
if(LOWORD(lParam) == FD_CLOSE)
{
EnableWindow(hButton, FALSE);
}
return 0;
case WM_COMMAND:
switch(wParam)
{
case IDOK:
iReturnValue = recv(c, szBuf, sizeof(szBuf), 0);
sprintf(szMsg, "recv retourne %d.", iReturnValue);
MessageBox(0, szMsg, "Valeur de retour de recv()", MB_OK);
return 0;
case IDCANCEL: EndDialog(hDlg, 0);
}
}
return 0;
}
0
sebseb42 Messages postés 495 Date d'inscription dimanche 6 juillet 2003 Statut Membre Dernière intervention 9 novembre 2007 1
28 juil. 2003 à 23:11
MDR

en gros, ton serveur il affiche tout le temps -1 quoi... tu t'es pas dit que c'etais peut-etre parcequil fonctionne pas :)

serieux ca me fait trop marrer quoi, enfin bon je commence a en avoir un peu marre de devoir rabacher tout le temps la meme chose, alors me crois pas si tu veux, moi je m'en fout, je sais que c'est pas possible que tu es des echange entre un meme client et un meme serveur apres que le serveur est eu un -1 sur recv, c'est tout

bon, pour te convaincre, je vais poster un pack que je vais intituler test_recv

tu verra par toi-meme qu'avec un programme bien ecrit, recv fonctionne comme je le dit et non pas comme tu le crois
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
28 juil. 2003 à 23:22
Perso je suis décu de ta reaction.
Je suis pas la pour me prendre la tete. J'essaye de te convaincre que recv qui retourne -1 en socket non bloquant, ca ne veut pas dire que le client a déco. Et je suis sur de ce que j'avance.

Si tu veux je reécris mon serveur pour qu'il affiche ce que le client lui dit, et qu'il echo au client cette meme phrase.
Et tjrs avec le bouton qui teste recv() lorsqu'on clique, ok ?

je veux pas te faire de peine, mais recv() qui retourne -1 quand un socket est non bloquant c'est tiré de msdn.

------------------------------
Réponse au message :
-------------------------------

> MDR
>
> en gros, ton serveur il affiche tout le temps -1 quoi... tu t'es pas dit que c'etais peut-etre parcequil fonctionne pas :)
>
> serieux ca me fait trop marrer quoi, enfin bon je commence a en avoir un peu marre de devoir rabacher tout le temps la meme chose, alors me crois pas si tu veux, moi je m'en fout, je sais que c'est pas possible que tu es des echange entre un meme client et un meme serveur apres que le serveur est eu un -1 sur recv, c'est tout
>
> bon, pour te convaincre, je vais poster un pack que je vais intituler test_recv
>
> tu verra par toi-meme qu'avec un programme bien ecrit, recv fonctionne comme je le dit et non pas comme tu le crois
>
0
sebseb42 Messages postés 495 Date d'inscription dimanche 6 juillet 2003 Statut Membre Dernière intervention 9 novembre 2007 1
28 juil. 2003 à 23:35
> Perso je suis décu de ta reaction.

bah je commence a en avoir marre, ca peut se comprendre

> Je suis pas la pour me prendre la tete.

moi non plus mais c'est ce qu'il se passe pourtant

> J'essaye de te convaincre que recv qui retourne -1 en
> socket non bloquant

pour ta gouverne, socket bloquant ou non n'influe pas sur le comportement da la fonction

et puis stp, n'essaye pas de me convaincre d'un truc faux, moi je n'essaye pas de faire ca

> je veux pas te faire de peine, mais recv() qui retourne -1
> quand un socket est non bloquant c'est tiré de msdn.

MDR serieux, relit ce que tu ecrit serieux... recv qui retourne -1 quand un socket est non bloquant... tu crois donc que parseque ton socket va etre bloquant alors il renvera jamais -1 et parcequil sera non bloquant, il aura alors le droit de renvoyer -1 ???

serieux c'est absurde...

bon, si tu connais les page de man, en voila un petit extrait

"These calls return the number of bytes received, or -1 if an error occurred."

alors quand tu me sort que tu as -1 au recv du serveur et que ton client est connecter, bah dsl mais ca me fait bien rire, et la, que tu soit decu ou pas, ca change rien, j'y peux rien mais c'est franchement marrant, et surtout stp... n'essaye pas de me convaincre que les pages de man sont eronner
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
28 juil. 2003 à 23:52
Dans l'extrait de man que tu cite, il ne parle pas de socket non bloquant.

La fonction recv appelle avec un socket non bloquant doit retourner la main tout de suite, et comme c'est instantané, il ne recois rien et provoque une erreur.
Il retourne donc SOCKET_ERROR defini a (-1) dans winsock2.h et place l'erreur WSAEWOULDBLOCK dans WSAGetLastError.
La fonction recv, tjrs avec un socket non bloquant, appellée apres un event FD_READ ne provoquera pas d'erreur car elle pourra lire les données tout de suite, et donc elle retournera -1.

Tout ce que je dis je l'invente pas, c'est tiré de msdn, et si tu veux je poste ici mon serveur-test qui fais echo et qui prouve cela, et je t'envoie meme la version exe si tu veux tester par toi meme.
0
Rejoignez-nous