begin process at 2012 05 29 03:26:47
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Archive C/C++

 > 

Archives

 > 

Réseau / Internet

 > 

gestion des event avec WSANETWORKEVENTS


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

gestion des event avec WSANETWORKEVENTS

vendredi 10 décembre 2004 à 19:11:06 | gestion des event avec WSANETWORKEVENTS

Spiffou

bonjour à tous,
je voudrais votre avis sur la gestion des evenements sur les sockets.
je réalise une application (un jeu) qui doit communiquer sur un réseau local. j prévois donc d'utiliser 2 thread, un d'envoi et un de reception.

j'ai plusieurs pb:
- la gestion des evenement ne marche pas, en effet, je crée bien les evenements avec (WSACreateEvent) et je les assigne au socket (WSAEventSelect). par contre, le pb se situe j pense au niveau de l'attente d'evenement (WSAWaitForMultipleEvents) parce que le programme semble se bloquer à ce niveau.

- de plus, lors de la gestion du serveur, je ne vois pas comment gérer les evenements après acceptation de la connexion (accept) car il y a création d'un autre socket pour les communication.
(j'ai bien lu l'histoire dans laquelle on crée un tableau cf le livre conseillé par aardman qui est tres bien; mais j n'arrive pas à l'implémenter) j'ai donc choisi de créer un autre évenement sans faire tte l'histoire du tableau mais ca ne marche pas, le prog se bloque à nouveau sur WSAWaitForMultipleEvents.

- enfin rassurez moi, il m'a semble que d'utiliser la gestion de socket avec WSAWaitForMultipleEvents etait un bon choix, j'ai bon...??


Désolé pour la longueur du post, et pour ceux qui auront le courage de lire, merci beaucoup pour vos réponses.


//
// Voila le Code Client:
//

#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")


int main(int argc, char ** argv)
{
char buffer[250];
int N_port = 6566; // numero du port de communication
int QUEUE = 5; // taille de la file d'attente pour la connection sur le listen socket
SOCKET C_socket;
SOCKADDR_IN C_adresse; // adresse du client

WSAEVENT hEvent[1];
WSANETWORKEVENTS NetworkEvent;

printf("Chat Client\n");

// initialisation de la connection
C_socket = socket(AF_INET, SOCK_STREAM, 0);
if(C_socket == -1)
{
printf("ERREUR : echac de la création de socket\n");
}

C_adresse.sin_family = AF_INET;
C_adresse.sin_port = htons(N_port);
C_adresse.sin_addr.s_addr = inet_addr("127.0.0.1");

hEvent[0] = WSACreateEvent();
WSAEventSelect(C_socket, hEvent[0], FD_WRITE | FD_READ | FD_CONNECT | FD_CLOSE);

printf("Demande de connexion au serveur 127.0.0.1\n");
connect(C_socket, (sockaddr*)&C_adresse, sizeof(C_adresse));

// Boucle de gestion des evenements
while(true)
{
printf("Client Gestion Event\n");

memset(&NetworkEvent, 0, sizeof(NetworkEvent));
WSAWaitForMultipleEvents(1, hEvent, 0, WSA_INFINITE, 0);
WSAEnumNetworkEvents(C_socket, hEvent[0], &NetworkEvent);

if(NetworkEvent.lNetworkEvents & FD_CONNECT)
{
printf("Client Event Connect\n");
// erreur a la connexion
if(NetworkEvent.iErrorCode[FD_CONNECT_BIT])
{
printf ("ERREUR : Connexion error\n");
break;
}
// si connexion ok, envoi de la requete
}

if (NetworkEvent.lNetworkEvents & FD_WRITE)
{
printf("Client Event Write\n");
if (NetworkEvent.iErrorCode[FD_WRITE_BIT] != 0)
{
printf("FD_WRITE failed with error %d\n", NetworkEvent.iErrorCode[FD_WRITE_BIT]);
break;
}
// envoie de données
send(C_socket,
buffer,
sizeof(buffer),
0);
}

if(NetworkEvent.lNetworkEvents & FD_READ)
{
printf("Client Event Read\n");
// erreur a la connexion
if(NetworkEvent.iErrorCode[FD_READ_BIT])
{
printf ("ERREUR : Read error\n");
break;
}
// lecture de donnees sur le socket
recv(C_socket,buffer, sizeof(buffer), 0);
}

if(NetworkEvent.lNetworkEvents & FD_CLOSE)
{
printf("Client Event Close\n");
// verifie s'il ne reste plus rien a lire sur le socket
do
{
memset(&NetworkEvent, 0, sizeof(NetworkEvent));
WSAEnumNetworkEvents(C_socket, 0, &NetworkEvent);
if(NetworkEvent.lNetworkEvents & FD_READ)
{
if(NetworkEvent.lNetworkEvents & FD_READ)
{
// erreur a la connexion
if(NetworkEvent.iErrorCode[FD_READ_BIT])
{
printf ("ERREUR : Read error\n");
break;
}
// lecture de donnees sur le socket
recv(C_socket,buffer, sizeof(buffer), 0);
}
}
}
while(NetworkEvent.lNetworkEvents & FD_READ);

}
}
return 0;
}


//
// Voila le Code Serveur:
//

// serveur.cpp : Defines the entry point for the console application.
//
#include "string.h"
#include "stdio.h"
#include "conio.h"
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib")


void accept(void);

int main(int argc, char* argv[])
{
char buffer[250];
SOCKET L_socket; // socket pour ecoute sur le reseau (listen)
SOCKET S_socket; // socket Serveur pour emission/reception sur le reseau

SOCKADDR_IN S_adresse; // adresse du serveur

int N_port = 6667; // numero du port de communication
int QUEUE = 5; // taille de la file d'attente pour la connection sur le listen socket

int Ret;
WSADATA WSAData;

WSAEVENT hEvent[2];
WSANETWORKEVENTS NetworkEvent,NewEvent;

printf("Chat Serveur !\n");

// initialisation de la connexion

if ((Ret = WSAStartup(MAKEWORD(2,2), &WSAData)) != 0)
{
printf("ERREUR :WSAStartup a echoue",Ret);
return (-1);
}

L_socket = socket( AF_INET,SOCK_STREAM,IPPROTO_TCP);
S_adresse.sin_family = AF_INET;
S_adresse.sin_addr.s_addr = htonl(INADDR_ANY);
S_adresse.sin_port = htons(N_port);

bind( L_socket,(SOCKADDR *)&S_adresse,sizeof(S_adresse));

// creation d'un evenement reseau
hEvent[0] = WSACreateEvent();

WSAEventSelect(L_socket, hEvent[0], FD_ACCEPT | FD_CLOSE);

listen(L_socket, QUEUE);

while(TRUE)
{
memset(&NetworkEvent, 0, sizeof(NetworkEvent));
WSAWaitForMultipleEvents(1, hEvent, 0, WSA_INFINITE, 0);
WSAEnumNetworkEvents(L_socket, hEvent[0], &NetworkEvent);

// Check for FD_ACCEPT messages
if (NetworkEvent.lNetworkEvents & FD_ACCEPT)
{
printf("Serveur Event Accept\n");
if (NetworkEvent.iErrorCode[FD_ACCEPT_BIT] != 0)
{
printf("FD_ACCEPT failed with error %d\n",NetworkEvent.iErrorCode[FD_ACCEPT_BIT]);
break;
}

// Accept a new connection, and add it to the
// socket and event lists
accept();
}

if (NetworkEvent.lNetworkEvents & FD_CLOSE)
{
printf("Serveur Event Close\n");
if (NetworkEvent.iErrorCode[FD_CLOSE_BIT] != 0)
{
printf("FD_CLOSE failed with error %d\n",NetworkEvent.iErrorCode[FD_CLOSE_BIT]);
break;
}
closesocket(S_socket);
}
}

// fermeture du socket
//--------------------
closesocket(S_socket);
closesocket(L_socket);

// liberation des ressources allouées pour la communication
//---------------------------------------------------------
if (WSACleanup() == SOCKET_ERROR)
{
printf("ERREUR : WSACleanup a echoue, erreur : %d\n", WSAGetLastError());
}
return 0;
}

void accept(void)
{
printf("Serveur ConneX Accept\n");

S_socket = accept(
L_socket,
NULL,
NULL);

// send de test
send(S_socket,
"ca marche",
9,
0);


hEvent[1] = WSACreateEvent();

WSAEventSelect(
S_socket,
hEvent[1],
FD_READ | FD_WRITE | FD_CLOSE);

while(true)
{
memset(&NewEvent, 0, sizeof(NewEvent));

WSAWaitForMultipleEvents(1, hEvent, 0, WSA_INFINITE, 0);
WSAEnumNetworkEvents(S_socket, hEvent[1], &NewEvent);


// Process FD_READ notification
if (NewEvent.lNetworkEvents & FD_READ)
{
printf("Serveur Event Read\n");
if (NewEvent.iErrorCode[FD_READ_BIT] != 0)
{
printf("FD_READ failed with error %d\n", NewEvent.iErrorCode[FD_READ_BIT]);
break;
}

// Read data from the socket
recv(S_socket,buffer, sizeof(buffer), 0);
}

// Process FD_WRITE notification
if (NewEvent.lNetworkEvents & FD_WRITE)
{
printf("Serveur Event Write\n");
if (NewEvent.iErrorCode[FD_WRITE_BIT] != 0)
{
printf("FD_WRITE failed with error %d\n", NewEvent.iErrorCode[FD_WRITE_BIT]);
break;
}

send(S_socket,
buffer,
sizeof(buffer),
0);
}

if (NewEvent.lNetworkEvents & FD_CLOSE)
{
printf("Serveur Event Close\n");
if (NewEvent.iErrorCode[FD_CLOSE_BIT] != 0)
{
printf("FD_CLOSE failed with error %d\n",NewEvent.iErrorCode[FD_CLOSE_BIT]);
break;
}
closesocket(S_socket);
}
}

}
vendredi 10 décembre 2004 à 22:07:16 | Re : gestion des event avec WSANETWORKEVENTS

aardman

Membre Club
Salut,
Perso j'ai pas reussi a compiler le code, y'a trop d'erreur. La fonction accept() porte le nom d'une fonction winsock, et en plus elle utilise plein de variables auxquelles elle n'a pas acces.

Concernant le serveur:
Il faut tenir a jour une variable avec le nombre de clients connectés.
Lorsqu'un client se connecte, la fonction accept de winsock te retourne le socket qui servira a communiquer avec le client. Ensuite il faut crééer un nouvel Event, appeler WSAEventSelect() pour associer l'event au socket handle, puis ajouter l'Event dans le tableau d'event (celui que tu passes a WSAWaitForMultipleEvents).
Lors d'une déconnexion, il faut fermer l'event, fermer le socket, suprimer l'event du tableau et réarranger le tableau pour suprimer la case vide (l'event que tu as suprimé) car sinon WSAWaitForMultipleEvents provoquera une erreur.

Aussi, il faut tenir compte de la valeur de retour de WSAWaitForMultipleEvents, car c'est elle qui te permet de savoir quel event est passé dans l'état signalé.
vendredi 10 décembre 2004 à 23:45:36 | Re : gestion des event avec WSANETWORKEVENTS

Spiffou

ok merci d'avori jeté un ptit coup d'oeil...
en fait ca compil tres bien chez moi tout ca, mais mes variables C_Socket et C_adresse etc... sont declarées en globales du coup la fonction accept y a bien acces. j'ai voulu compresser le code pour mettre sur le site et j'ai aps fait gaffe...

par contre en effet accept est un fonction winsock du coup il y a surment un pb à ce niveau.

Sinon, à mon avis le client marche (je me suis bcp inspiré de ton code pour le dl d'un fichier en ligne ;) ), masi le serveur à un pb de gestion de la fonction WSAWaitForMultipleEvents ...

justement je me perds un peu dans l'utilisation de la var de retour etc, en fait je ne sais plus trop comment faire quoi.
je vais reflechir à tout ca demain et quand ce sera clair je referrai une reponse plus sensée. (pour l'instant je vais plutot reviser mon exam de demain matin... sniff)

en tt cas, les fait de gerer la fonction accept dasn une fonction séparée(qui en plus s'appelle accept...) me semble pas tres approprié en cas de fermeture du socket de communication quand la fonction va retourner, on sera tjs dans la boucle de gestion des events du socket d'ecoute... en plus, au niveau thread et asynchrone, en admettant qu'il y ai d'autres demandes de connexion, elle ne seront pas prises en compte puisqu'on ne gere plus les events sur le socket d'ecoute ... je me trompe pas là si?
--> c'est ma tt ca...
je pense que je vais utiliser une autre technique pour mon appli, par ctre j'aimerai bien faire marcher tt ca histoire de pas avoir commencé à apprendre pour rien... et surtt de pas tt gacher en arretant en route.

merci bcp encore d'avoir regardé
vendredi 10 décembre 2004 à 23:56:06 | Re : gestion des event avec WSANETWORKEVENTS

aardman

Membre Club
Salut,
En effet la fonction accept ne sert a rien et bloque le code.
WSAWaitForMultipleEvents peut gerer jusqu'a 64 events, donc tu n'a besoin que d'une boucle while (et donc 1 seul thread) pour gerer tout les evenements reseau de 64 sockets differents.
dimanche 12 décembre 2004 à 19:49:50 | Re : gestion des event avec WSANETWORKEVENTS

Spiffou

voila j'ai corrigé mon code et j'ai bien utilisé la sortie de WSAWaitForMultipleEvents pour la gestion des evenements et des differents sockets...
le pb c'est que le prog ne fait rien, il n'établit mm pas la connexion et là je ne comprend pas pourquoi...
(ca semble etre tjs bloqué sur WSAWaitForMultipleEvents )
je n'ai pas encore géré la sortie de l'appli (fermeture des sockets et mise à jour des tableaux d'evenements) mais je ne pense pas que ce soit ca qui l'empeche de se connecter.

d'autre par pour envoyer des données, comment fait on pour déclencher l'event qui est sensé entrainer l'envoi du buffer. puisque l'envoi de donnée est a l'initiative de l'appli, je ne vois pas bien comment l'effectuer.


revoila mon code qui cette fois doit compiler sans erreur avec un simple copier/coller...


merci beaucoup à tous...





// CODE SERVEUR
//---------------

#include "string.h"
#include "stdio.h"
#include "conio.h"
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib")

// Définition des variables Globables :
//-------------------------------------
#define NB_CONNEC_MAX 2

SOCKET L_socket; // socket pour ecoute sur le reseau (listen)
SOCKET S_socket; // socket Serveur pour emission/reception sur le reseau

SOCKADDR_IN S_adresse; // adresse du serveur

int N_port = 6566; // numero du port de communication
int QUEUE = 5; // taille de la file d'attente pour la connection sur le listen socket

WSAEVENT NewEvent,EventArray[3];
WSANETWORKEVENTS NetworkEvent;
SOCKET SocketArray [WSA_MAXIMUM_WAIT_EVENTS];
DWORD EventTotal = 0;
DWORD Index, i;

int main(int argc, char* argv[])
{

int k=0,j=0;
int Ret;

WSADATA WSAData;
char buffer[250];
char *Sbuffer;
Sbuffer = (char*)malloc(250);
Sbuffer = strdup ("envoi du serveur");

printf("CHAT SERVEUR\n");

// initialisation de Winsock version 2.2
//--------------------------------------
if ((Ret = WSAStartup(MAKEWORD(2,2), &WSAData)) != 0)
{
printf("ERREUR :WSAStartup a echoue",Ret);
return (-1);
}

// Création du socket d'écoute sur le reseau
// (demande de connexion client)
//-------------------------------------------
L_socket = socket( AF_INET, // famille d'adresse du protocol (ici IPv4)
SOCK_STREAM, // type de socket du protocol (ici TPC/IP)
IPPROTO_TCP); // protocol utilisé (ici TCP/IP)

// remplissage de la structure d'adressage winsock
// pour les communication reseau en IPv4
//------------------------------------------------
S_adresse.sin_family = AF_INET;
S_adresse.sin_addr.s_addr = htonl(INADDR_ANY);
S_adresse.sin_port = htons(N_port);

// Bind du Socket
// association de l'adresse avec le socket
//----------------------------------------
bind( L_socket, (SOCKADDR *)&S_adresse, sizeof(S_adresse));


// creation d'un evenement reseau
NewEvent = WSACreateEvent();

WSAEventSelect(L_socket, NewEvent, FD_ACCEPT | FD_CLOSE );

// mise à l'écoute de demande de connection client
// on utilise une file d'attente de 5 place
//------------------------------------------------
listen(L_socket, QUEUE);


SocketArray[EventTotal] = L_socket;
EventArray[EventTotal] = NewEvent;
EventTotal++;

printf("en attente de demande de connexion\n");

while(TRUE)
{

WSAWaitForMultipleEvents(1, EventArray, 0, WSA_INFINITE, 0);
WSAEnumNetworkEvents(L_socket, EventArray[0], &NetworkEvent);


// Wait for network events on all sockets
Index = WSAWaitForMultipleEvents(EventTotal,EventArray, FALSE, WSA_INFINITE, FALSE);
// permet de deduire de quel socket vient l'evenement
Index = Index - WSA_WAIT_EVENT_0;

// Iterate through all events to see if more than one is signaled
for(i=Index; i < EventTotal ;i++)
{
Index = WSAWaitForMultipleEvents(1, &EventArray[i], TRUE, 1000, FALSE);
if ((Index != WSA_WAIT_FAILED) || (Index != WSA_WAIT_TIMEOUT))
{
Index = i;

WSAEnumNetworkEvents(
SocketArray[Index],
EventArray[Index],
&NetworkEvent);


// Check for FD_ACCEPT messages
if (NetworkEvent.lNetworkEvents & FD_ACCEPT)
{
if (NetworkEvent.iErrorCode[FD_ACCEPT_BIT] != 0 && EventTotal >= NB_CONNEC_MAX)
{
printf("FD_ACCEPT failed with error %d\n",NetworkEvent.iErrorCode[FD_ACCEPT_BIT]);
break;
}

printf("reception et acceptation de la connexion\n");

// Accept a new connection, and add it to the
// socket and event lists
int taille_adr = sizeof (S_adresse);
S_socket = accept(L_socket, (SOCKADDR *)&S_adresse, &taille_adr);

// creation d'un evenement reseau
NewEvent = WSACreateEvent();

WSAEventSelect(S_socket, NewEvent, FD_CLOSE | FD_READ | FD_WRITE);

SocketArray[EventTotal] = S_socket;
EventArray[EventTotal] = NewEvent;
EventTotal++;

printf("connexion acceptee\n");
}

if(NetworkEvent.lNetworkEvents & FD_READ)
{
// erreur a la connexion
if(NetworkEvent.iErrorCode[FD_READ_BIT])
{
printf("FD_READ failed with error %d\n", NetworkEvent.iErrorCode[FD_READ_BIT]);
break;
}
// Read data from the socket
recv(S_socket,buffer, sizeof(buffer), 0);
j++;
printf(">>%d - %s\n",j,buffer);
}

if(NetworkEvent.lNetworkEvents & FD_WRITE)
{
// erreur a la connexion
if(NetworkEvent.iErrorCode[FD_WRITE_BIT])
{
printf("FD_WRITE failed with error %d\n", NetworkEvent.iErrorCode[FD_WRITE_BIT]);
break;
}
// envoie de données
send(S_socket, Sbuffer, sizeof(Sbuffer), 0);
k++;
printf ("<<%d - %s\n",k,Sbuffer);

}

if(NetworkEvent.lNetworkEvents & FD_CLOSE)
{
if (NetworkEvent.iErrorCode[FD_CLOSE_BIT] != 0)
{
printf("FD_CLOSE failed with error %d\n",NetworkEvent.iErrorCode[FD_CLOSE_BIT]);
break;
}
// verifie s'il ne reste plus rien a lire sur le socket
do {
memset(&NetworkEvent, 0, sizeof(NetworkEvent));
WSAEnumNetworkEvents(S_socket, 0, &NetworkEvent);
if(NetworkEvent.lNetworkEvents & FD_READ)
{
}
}while(NetworkEvent.lNetworkEvents & FD_READ);
}
}
}
}

// fermeture du socket
//--------------------
closesocket(S_socket);


// liberation des ressources allouées pour la communication
//---------------------------------------------------------
if (WSACleanup() == SOCKET_ERROR)
{
printf("ERREUR : WSACleanup a echoue, erreur : %d\n", WSAGetLastError());
}
return 0;
}




// CODE CLIENT
//-------------
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")


int main(int argc, char ** argv)
{
char buffer[250];
char *Sbuffer;
Sbuffer = (char*)malloc(250);
int i=0,j=0;

SOCKET C_socket;
SOCKADDR_IN C_adresse; // adresse du client
int N_port = 6566; // numero du port de communication


WSAEVENT hEvent[1];
WSANETWORKEVENTS NetworkEvent;

printf ("CHAT CLIENT\n");

Sbuffer = strdup("envoi du client");

// initialisation de la connexion
C_socket = socket(AF_INET, SOCK_STREAM, 0);
if(C_socket == -1)
{
}

C_adresse.sin_family = AF_INET;
C_adresse.sin_port = htons(N_port);
C_adresse.sin_addr.s_addr = inet_addr("127.0.0.1");

hEvent[0] = WSACreateEvent();
WSAEventSelect(C_socket, hEvent[0], FD_WRITE | FD_READ | FD_CONNECT | FD_CLOSE);

connect(C_socket, (sockaddr*)&C_adresse, sizeof(C_adresse));
printf ("en attente de connexion\n");


// gestion des evenement
while(true)
{
memset(&NetworkEvent, 0, sizeof(NetworkEvent));

WSAWaitForMultipleEvents(1, hEvent, 0, WSA_INFINITE, 0);
WSAEnumNetworkEvents(C_socket, hEvent[0], &NetworkEvent);

// verification que la connexio s'est bien faite
if(NetworkEvent.lNetworkEvents & FD_CONNECT)
{
// erreur a la connexion
if(NetworkEvent.iErrorCode[FD_CONNECT_BIT])
{
printf("Erreur lors de la connexion.\n");
break;
}
// si connexion ok, envoi de la requette
printf ("connexion etablie\n");
}

if(NetworkEvent.lNetworkEvents & FD_READ)
{
// erreur a la connexion
if(NetworkEvent.iErrorCode[FD_READ_BIT])
{
printf("FD_READ failed with error %d\n", NetworkEvent.iErrorCode[FD_READ_BIT]);
break;
}
// Read data from the socket
recv(C_socket,buffer, sizeof(buffer), 0);
j++;
printf(">>%d - %s\n",j,buffer);
}

if(NetworkEvent.lNetworkEvents & FD_WRITE)
{
// erreur a la connexion
if(NetworkEvent.iErrorCode[FD_WRITE_BIT])
{
printf("FD_WRITE failed with error %d\n", NetworkEvent.iErrorCode[FD_WRITE_BIT]);
break;
}
// envoie de données
send(C_socket, Sbuffer, sizeof(Sbuffer), 0);
i++;
printf ("<<%d - %s\n",i,Sbuffer);

}

if(NetworkEvent.lNetworkEvents & FD_CLOSE)
{
if (NetworkEvent.iErrorCode[FD_CLOSE_BIT] != 0)
{
printf("FD_CLOSE failed with error %d\n",NetworkEvent.iErrorCode[FD_CLOSE_BIT]);
break;
}
// verifie s'il ne reste plus rien a lire sur le socket
do {
memset(&NetworkEvent, 0, sizeof(NetworkEvent));
WSAEnumNetworkEvents(C_socket, 0, &NetworkEvent);
if(NetworkEvent.lNetworkEvents & FD_READ)
{
}
}while(NetworkEvent.lNetworkEvents & FD_READ);
}
}
return 0;
}

dimanche 12 décembre 2004 à 20:06:55 | Re : gestion des event avec WSANETWORKEVENTS

aardman

Membre Club
Salut,
coté serveur j'ai pas vraiment compris ce que tu faisais:

Tu appeles WSAWaitForMultipleEvents, puis WSAEnumNetworkEvents, puis tu reappeles WSAWaitForMultipleEvents, ce qui donne:

Lorsque EventArray[0] passe a l'etat signalé, le 1er WSAWaitForMultipleEvents retourne, puis WSAEnumNetworkEvents se charge de remetre l'event a l'etat non signalé, et donc le 2eme WSAWaitForMultipleEvents bloque tout ...

voila un probleme, je suis pas allé plus loin.
dimanche 12 décembre 2004 à 20:34:12 | Re : gestion des event avec WSANETWORKEVENTS

Spiffou

en effet, un bete oubli dans le code... par ctre ca ne change rien au pb, le blocage semble tjs etre le mm...

je dois mal comprendre ton livre sur la prog reseau...

en tt cas je n'arrive pas à passer le premier WSAWaitForMultipleEvents, il se bloque dessus...
---> il n'y a donc pas d'evenement reseau?? pourtant je crois que mon initialisation de connexion est valide...
dimanche 12 décembre 2004 à 20:49:57 | Re : gestion des event avec WSANETWORKEVENTS

aardman

Membre Club
Salut,
Perso j'arrive a me connecter au server avec telnet donc le serveur accepte bien la 1ere connexion.

Par contre quand je tape quelque chose avec telnet ca m'affiche plein de caractere, c'est parceque tu fait directement un printf sur ce que tu recois sans rajouter le 0 final de la chaine.
dimanche 12 décembre 2004 à 20:56:19 | Re : gestion des event avec WSANETWORKEVENTS

aardman

Membre Club
Salut,
J'ai oublié une question que tu as posé plus haut, concernant l'envoie des donnés:
C'est simple, tu peux faire un send n'importe ou dans le code, et l'evenement FD_WRITE sera généré. Cet evenement te permet juste de verifier qu'il n'y a pas eu d'erreur lors de l'envoi.

Tu n'a pas a appeler send() lors du traitement de cet event, sauf dans certains cas précis, lorsque tu veux que les send se fassent automatiquement les uns a la suite des autres, par exemple dans le cas d'un transfers de fichiers.
dimanche 12 décembre 2004 à 22:37:09 | Re : gestion des event avec WSANETWORKEVENTS

Spiffou

oui merci pour le coup du zero, je corrige l'erreur...
j'en corrige aussi une autre:
recv(C_socket,buffer, strlen(buffer), 0);
en non pas
recv(C_socket,buffer, sizeof(buffer), 0);
car buffer est un pointeur donc 4 octets, rien à voir avec la taille reelle de la chaine... j'en profite pour proteger le printf en ajoutant le \0 de fin de chaine:
// Read data from the socket
nb_octets = recv(S_socket,buffer, strlen(buffer), 0);
if (nb_octets != -1)
{
buffer[nb_octets] = '\0';
j++;
printf(">>%d - %s\n",j,buffer);
}


par contre je suis pas sur de bien avoir compris pour le coup de send.
lorsque je fais send ailleurs dans mon prog, je declenche l'event FD_WRITE, et ca fait juste un controle d'erreur... (mais alors pkoi on recode le send dans la gestion de l'event FD_WRITE:
if(NetworkEvent.lNetworkEvents & FD_WRITE)
{
// erreur a la connexion
if(NetworkEvent.iErrorCode[FD_WRITE_BIT])
{
printf("FD_WRITE failed with error %d\n", NetworkEvent.iErrorCode[FD_WRITE_BIT]);
break;
}
// envoie de données
send(C_socket, Sbuffer, sizeof(Sbuffer), 0);
i++;
printf ("<<%d - %s\n",i,Sbuffer);
}

quand on fait ca ca ne fait pas un deuxieme send qui envoie buffer??
ou alors c'est l'histoire du transfert de fichier (ce qui n'est pas mon cas) donc il faudrait que je l'enlève c'est bien ca. c'est juste utiliser pour lancer l'envoi du paquet suivant quand les buffer est trop petit pour contenir la donnee à envoyer...


enfin, comme tu m'a dis qu'apparement le serveur acceptais les connexions, j suppose que mon client doit mal faire la demande, puisqu'il ne se passe rien je vais essayer de reverifier, mais il me semblait que tt etait correct coté client puisque c'est tres proche de ta source sur le transfert de ficheir en http et que j'avais testé mes parametres avant... ou alors j'ai encore mal implémenté un truc...

en tt cas merci pour tes conseils et bravo pour tes connaissances en prog socket...
^^

1 2 3 4

Cette discussion est classée dans : printf, socket, read, fd, networkevent


Répondre à ce message

Sujets en rapport avec ce message

Problème avec la fonction read du C sous linux. [ par bouba ] Bonjour, j'ai un problème que je ne comprend pas avec la fonction read, le problème vient lorsque j'essai de lire 4 ocets à mettre dans un entier.J'es Winsock2 WASEvents... [ par fraboulet ] Bonjour à tous,J'ai une question concernant winsock2, je souhaite faire un thread d'écoute de sockets. Mais je souhaite pouvoir ajouter dynamiquement [C] Un timeOut sur Socket en détails [Linux] [ par ZedMaTrix ] Salut a tous.Bon j'ai pas mal cherché sur le site, et appart des débuts de réponses, je n'ai rien trouvé qui m'ai aidé à résoudre ce problème de TimeO Envois et reception de commande [ par t0Xic_h ] SalutVoici mon code source .La connection entre le client et le serveur se passe bien, mais je n'ai pas su ecrirele code qui me permettera d'envoyer l Problème de lecture fichier [ par nach73 ] J'ai un enorme probleme je n'arrive pas a lire dans mon fichierVoila la partie de mon programme.Si quelqu'un peux m'aide.Merci.//ouverture du fichier https (SSL) et CPP [ par abdoulax ] Bonjours je débute dans la sécurité de transfert de données. Pour sécuriser mes données j'ai choisie le protocole HTTPS (paraît-il que FTPS n'est pas erreur [ par jekburn ] Bonjour, mon programme refuse de fonctionné, il commet une erreur mémoireMerci pour votre aide#include #include #include struct enreg{ char nom[30];& erreur d'application............please.help........... [ par jekburn ] #include #include #include struct enreg{ char nom[30]; char tel[10];}fiche; creation(){ clrscr(); FILE *fd; fd=fopen("fichier.dat"," crash de lapplication au moment de FD_READ ou FD_CLOSE [ par thejojo1 ] Voila un drôle de problème. J'ai codé un serveur en utilisant la fonctionWSAAsyncSelect(sock,hwnd,1025,FD_READ | FD_WRITE | FD_CLOSE | FD_ACCEPT);Jarr probleme de recherche dans un fichier [ par jekburn ] // Bonsoir, mon programme est un repertoire téléphonique, on peut rentré un nom et // un n° de tél.// les données s'incrivent bien dans le fichier, ma


Nos sponsors


Sondage...

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

Photothèque

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 : 0,780 sec (4)

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