WSAAsyncselect pour client TCP [Résolu]

daviid00 3 Messages postés jeudi 15 décembre 2005Date d'inscription 24 février 2010 Dernière intervention - 23 févr. 2010 à 13:10 - Dernière réponse : daviid00 3 Messages postés jeudi 15 décembre 2005Date d'inscription 24 février 2010 Dernière intervention
- 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;
}
Afficher la suite 

Votre réponse

5 réponses

Meilleure réponse
cs_aardman 1905 Messages postés mercredi 22 janvier 2003Date d'inscription 17 septembre 2012 Dernière intervention - 23 févr. 2010 à 21:05
3
Merci
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(;;)

Merci cs_aardman 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 93 internautes ce mois-ci

Commenter la réponse de cs_aardman
cs_aardman 1905 Messages postés mercredi 22 janvier 2003Date d'inscription 17 septembre 2012 Dernière intervention - 23 févr. 2010 à 18:02
0
Merci
Salut,
ou est la boucle de traitement des messages ?
je pense qu'il faudrait remplacer le for(;;) {} par autre chose.
Commenter la réponse de cs_aardman
daviid00 3 Messages postés jeudi 15 décembre 2005Date d'inscription 24 février 2010 Dernière intervention - 23 févr. 2010 à 19:00
0
Merci
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
Commenter la réponse de daviid00
cs_aardman 1905 Messages postés mercredi 22 janvier 2003Date d'inscription 17 septembre 2012 Dernière intervention - 23 févr. 2010 à 20:59
0
Merci
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.
Commenter la réponse de cs_aardman
daviid00 3 Messages postés jeudi 15 décembre 2005Date d'inscription 24 février 2010 Dernière intervention - 24 févr. 2010 à 10:29
0
Merci
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.
Commenter la réponse de daviid00

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.