WSAAsyncselect pour client TCP

Résolu
daviid00 Messages postés 3 Date d'inscription jeudi 15 décembre 2005 Statut Membre Dernière intervention 24 février 2010 - 23 févr. 2010 à 13:10
daviid00 Messages postés 3 Date d'inscription jeudi 15 décembre 2005 Statut Membre Dernière intervention 24 février 2010 - 24 févr. 2010 à 10:29
Bonjour,

Je suis entrain de développer un client TCP qui se connecte de manière asynchrone à un serveur. Pour ce faire j'utilise la fonction WSAAsyncselect().

Mon problème est le suivant. Le client envoie une demande de connexion via la fonction connect(). Cette dernière génère un évènement FD_ACCEPT sur le serveur. Il accepte la connexion par la fonction accept(). Une fois que la connexion est établie, la CALLBACK fonction du client n'est pas appelée : l'évènement FD_CONNECT n'est pas généré. Malgré mes recherches sur internet, je ne suis pas en mesure d'identifier le problème.

Ci-dessous se trouve le code du client TCP :

#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>

#define DEFAULT_PORT 5150
#define WM_SOCKET (WM_USER + 1)


HWND MakeWorkerWindow(void);
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int main(int argc, char **argv)

{
WSADATA wsd;
SOCKET sClient;
int ret, i;
struct sockaddr_in server;
struct hostent *host = NULL;
HWND Window;

if ((Window MakeWorkerWindow()) NULL)
{
printf("MakeWorkerWindow() failed!\n");
return 1;
}
else
{
printf("MakeWorkerWindow() is OK!\n");
}

if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
printf("Failed to load Winsock library! Error %d\n", WSAGetLastError());
return 1;
}
else
{
printf("Winsock library loaded successfully!\n");
}

// Create the socket, and attempt to connect to the server
sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sClient == INVALID_SOCKET)
{
printf("socket() failed with error code %d\n", WSAGetLastError());
return 1;
}
else
{
printf("socket() looks fine!\n");
}


if (WSAAsyncSelect(sClient, Window, WM_SOCKET, FD_CONNECT | FD_READ| FD_WRITE) == 0)
{
printf("WSAAsyncSelect() is OK lol!\n");
}
else
{
printf("WSAAsyncSelect() failed with error code %d\n", WSAGetLastError());
}

server.sin_family = AF_INET;
server.sin_port = htons(DEFAULT_PORT);
server.sin_addr.s_addr = inet_addr("127.0.0.1");

connect(sClient, (struct sockaddr *)&server, sizeof(server));

for(;;)
{
}
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
printf("Message is %d\n", uMsg);

if (uMsg == WM_SOCKET)
{
if (WSAGETSELECTERROR(lParam))
{
printf("Socket failed with error %d\n", WSAGETSELECTERROR(lParam));
}
else
{
printf("Socket looks fine!\n");
switch(WSAGETSELECTEVENT(lParam))
{
case FD_CONNECT:
printf("Socket number %d connected\n", wParam);
break;

case FD_READ:
printf("Server can read\n");
break;

case FD_WRITE:
printf("Server can be written\n");
break;
}
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

HWND MakeWorkerWindow(void)
{
WNDCLASS wndclass;
CHAR *ProviderClass = "AsyncSelect";
HWND Window;

wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = (WNDPROC)WindowProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = NULL;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = ProviderClass;


if (RegisterClass(&wndclass) == 0)
{
printf("RegisterClass() failed with error %d\n", GetLastError());
return NULL;
}
else
{
printf("RegisterClass() is OK!\n");
}

// Create a window
if ((Window = CreateWindow(
ProviderClass,
"",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
NULL,
NULL)) == NULL)
{
printf("CreateWindow() failed with error %d\n", GetLastError());
return NULL;
}
else
{
printf("CreateWindow() is OK!\n");
}

return Window;
}

5 réponses

cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
23 févr. 2010 à 21:05
ton serveur possede bien cette boucle:
while(Ret = GetMessage(&msg, NULL, 0, 0))
tu n'as qu'a la copier dans ton client a la place du for(;;)
3
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
23 févr. 2010 à 18:02
Salut,
ou est la boucle de traitement des messages ?
je pense qu'il faudrait remplacer le for(;;) {} par autre chose.
0
daviid00 Messages postés 3 Date d'inscription jeudi 15 décembre 2005 Statut Membre Dernière intervention 24 février 2010
23 févr. 2010 à 19:00
Salut,

Merci pour ta réponse.

J'ai mis cette boucle for(;;) afin d'isoler le problème. Une fois que le client a envoyé la demande de connexion, il ne fait plus rien. Normalement il devrait sortir de cette boucle for via l'évènement FD_CONNECT puis y retourner.

Le problème sera résolu si le message ("Socket number %d connected\n", wParam) s'inscrit sur la console d'application du client, ce qui n'est pas le cas actuellement

Peut-être que je n'ai pas bien compris l'enchainement client-serveur. Une fois la connexion acceptée par le serveur, le client doit-il effectuer une requête particulière avant de recevoir l'évènement FD_CONNECT ?

Ci-dessous se trouve un lien avec les projets du client et du serveur :

- http://dl.free.fr/aSazaAHif => client
- http://dl.free.fr/afErwppr0 => serveur
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
23 févr. 2010 à 20:59
Salut,
en général, quand on rentre dans une boucle infinie, on en ressort jamais! à partir de ça, tu ne devrais pas être étonné de ne rien voir s'afficher dans ton programme.
comme je te l'ai dis tout a l'heure, il te manque une boucle de traitement de messages qui permettra de traiter tout les messages que reçoit ta fenêtre. j'imagine que ton WM_SOCKET avec FD_CONNECT est correctement posté dans la pile de message, mais vu que tu n'a rien qui dépile & traite ces messages, rien ne se passe.
0

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

Posez votre question
daviid00 Messages postés 3 Date d'inscription jeudi 15 décembre 2005 Statut Membre Dernière intervention 24 février 2010
24 févr. 2010 à 10:29
Le problème est solutionné en remplaçant la boucle for(;;) par le code suivant :

while(ret = GetMessage(&msg, NULL, 0, 0))
{
DispatchMessage(&msg);
}

Merci pour ton aide.
0
Rejoignez-nous