Accueil > Forum > > > > problème avec WSAGetLastError()
problème avec WSAGetLastError()
samedi 1 juillet 2006 à 04:13:10 |
problème avec WSAGetLastError()

fredo2009
|
Bonjour @ tous
Je suis en train de coder un scanner multithread avec socket non bloquant. Mon soucis est de récupérer le message d'erreur résultant du connect: si la connexion a réussi ou bien si elle a été refusée ou bien fermer le socket qd le timeout est dépassé.
En mode bloquant , je récupère bien le GetLastError() mais je ne peux pas régler le timeout du socket: if(connect(mysock,(struct sockaddr *) & server,sizeof(server))!=0) { code=GetLastError();
if(code==10061) {printf("la connexion sur le port %d a ete refusee \n",port);}
} else { printf("la connexion sur le port %d a reussie\n",port); }
en mode non bloquant, select me renvoie la même erreur 0 pour le time out dépassé et la connexion refusée. Et pour la connexion réussie je reçois l'erreur 10035.
[code]connect(conf->sock, (SOCKADDR *)&(conf->sin), sizeof(conf->sin));
int codeRetour = select(0,&socketToCheck,&socketToCheck,&socketToCheck,&tempo);
conf->code=GetLastError(); if (conf->code==10061) { printf("la connexion sur le port %d a ete refusee \n",port); closesocket(conf->sock); shutdown(conf->sock,2); } else { printf("la connexion sur le port %d a reussie\n",port); closesocket(conf->sock); shutdown(conf->sock,2); } [/code]
|
|
samedi 1 juillet 2006 à 21:00:36 |
Re : problème avec WSAGetLastError()

excrt
|
tu ne peux pas envoyer le même « fd_set » aux trois « fd_set » que select() attent. select() modifie les « fd_set » qu'il recoit. en passant, toi tu utilises « GetLastError() » et non « WSAGetLastError() »
//fd_set fdsread; // inutile pour un connect() fd_set fdswrite; fd_set fdserror; timeval timeout; int retval; unsigned long noblock = 1;
//ref::http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/ioctlsocket_2.asp ioctlsocket(conf->sock, FIONBIO, &noblock);
// initialize les « fd_set » FD_ZERO(&fdswrite); FD_ZERO(&fdserror);
// ajoute notre socket FD_SET(conf->sock, &fdswrite); FD_SET(conf->sock, &fdserror);
// le timeout timeout.tv_sec = X;
timeout.tv_msec = Y;
// connect( ... );
ref::http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/select_2.asp retval = select(0, NULL, &fdswrite, &fdserror, &timeout);
if (retval > 0) { if ( FD_ISSET(conf->sock, &fdswrite) ) { // ready } else if ( FD_ISSET(conf->sock, &fdserror) ) { printf("socket error: %d\n", WSAGetLastError()); } } else if (retval == 0) { puts("timeout"); } else if (retval == SOCKET_ERROR) { printf("select() error: %d\n", WSAGetLastError()); }
pour les codes/messages d'erreurs: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/system_error_codes.asp
-=-= ExCRT =-=-
|
|
lundi 3 juillet 2006 à 03:03:40 |
Re : problème avec WSAGetLastError()

fredo2009
|
C vrai que c plus propre comme ça. Mais le résultat n'est pas encore correct.
Par ex je devrais obtenir qque chose comme ceci:
port 110 occupe WSAGetLastError = 0 //la connexion a reussie sur ce port port 111 ferme WSAGetLastError = 10060 //timeout port 112 ferme WSAGetLastError = 10060 //timeout port 113 libre WSAGetLastError = 10061 //la connexion a ete expressement refusee
Et au lieu de ça j'obtiens: port 110 occupe WSAGetLastError = 10035 port 111 timeout WSAGetLastError = 0 port 112 timeout WSAGetLastError = 0 port 113 libre WSAGetLastError = 0 port 114 timeout WSAGetLastError = 0 port 115 timeout WSAGetLastError = 0 port 116 select() error = 10038 port 117 timeout WSAGetLastError = 0 port 141 select() error = 10038
Je n'ai donc pas les messages d'erreur attendu. De plus le code erreur 10038 arrive aléatoirement. Je peux scanner 2 fois le même port, il ne sortira pas à chaque fois cette erreur. Et si j'augmente le nbre de thread à plus de 9, le port 113 apparait en timeout.
Voilà le code complet :
#include "winsock2.h" #include <stdio.h> #include <stdlib.h> #pragma comment(lib, "ws2_32.lib") #include <time.h> #include "String.h" #include <winbase.h>
struct config { int sock; sockaddr_in sin; int ip; int port; int code; HANDLE hthread; MSG msg; FILE * fic; //pour enregistrer ds un fichier les résultats. Qd le code sera au point ^^ };
DWORD WINAPI connection( LPVOID Param ) { struct config * conf = (struct config *)Param; WSADATA WSAData; WSAStartup(MAKEWORD(2,2), &WSAData); conf->sock = socket(PF_INET,SOCK_STREAM,0); conf->sin.sin_addr.s_addr = ntohl(conf->ip); conf->sin.sin_family = AF_INET; conf->sin.sin_port = ntohs(conf->port); //Passage de la socket en mode non bloquant unsigned long optVal=1; ioctlsocket(conf->sock,FIONBIO,&optVal); //fd_set fdsread; // inutile pour un connect() fd_set fdswrite; fd_set fdserror;
timeval tempo; tempo.tv_sec = 2; //en s tempo.tv_usec = 0; //en ms // initialize les « fd_set » FD_ZERO(&fdswrite); FD_ZERO(&fdserror); // ajoute notre socket FD_SET(conf->sock, &fdswrite); FD_SET(conf->sock, &fdserror); connect(conf->sock, (SOCKADDR *)&(conf->sin), sizeof(conf->sin));
int retval = select(0, NULL, &fdswrite, &fdserror, &tempo); if (retval > 0) { if ( FD_ISSET(conf->sock, &fdswrite) ) { printf ("port %d occupe WSAGetLastError %d\n",conf->port, WSAGetLastError()); // ready } else if ( FD_ISSET(conf->sock, &fdserror) ) { printf("port %d libre WSAGetLastError %d\n",conf->port, WSAGetLastError()); } } else if (retval == 0) { printf("port %d timeout WSAGetLastError %d\n",conf->port,WSAGetLastError()); } else if (retval == SOCKET_ERROR) { //if (WSAGetLastError()!=10038) { printf("port %d select() error: %d\n",conf->port, WSAGetLastError()); } } //on repasse en mode bloquant optVal = 0; ioctlsocket (conf->sock, FIONBIO, &optVal); shutdown(conf->sock,2); closesocket(conf->sock); WSACleanup(); free(conf); return 0; } int main(int argc, char *argv[]) { if ( argc == 4) { struct config * conf = NULL; int nbrethread; int nthread; int portascanner; int scanip; portascanner = atoi(argv[1]); nbrethread = atoi(argv[2]); scanip = htonl(inet_addr(argv[3])); SetTimer(NULL,NULL,2000,NULL); for (;;) { nthread = nbrethread; for (;nthread>0;nthread--) { conf = (struct config *) malloc(sizeof(struct config) ); conf->ip = scanip; conf->port=portascanner; conf->hthread = CreateThread(NULL, 0, &connection, conf, 0, 0); CloseHandle(conf->hthread); portascanner++; } //ptite tempo de 2s entre chaque série de thread GetMessage(&conf->msg,NULL,0,0); while (conf->msg.message!=WM_TIMER) {;;} CloseHandle(conf->hthread); } KillTimer(NULL,NULL); return 0; } else { printf("Usage : scan.exe port_debut nthread ip\n"); return 0; } }
|
|
lundi 3 juillet 2006 à 16:59:47 |
Re : problème avec WSAGetLastError()

excrt
|
WSAStartup() tu dois l'appeler « une fois par _Process_ », pas par thread ...
int main() { // ... WSAStartup(..., ...);
// ...
WSACleanup(); return 0; }
après l'appel a select(), si ton socket est présent dans « fdswrite » c'est qu'il est pret pour l'envoie de données, donc, connexion réussi, pas d'échec. s'il est présent dans fdserror c'est qu'il y a erreur, donc la connexion a probablement échouée ...
tu peux récupérer le code d'erreur associé a chacun des sockets via « getsockopt() »
int getSocketError(SOCKET sock) { int error_code; int size = sizeof(int);
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error_code, &size) != SOCKET_ERROR) { return error_code; } return WSAGetLastError(); }
if ( FD_ISSET(conf->sock, &fdserror) ) { printf("socket error %d\n", getSocketError(conf->sock)); }
pour tes « include »
#pragma comment(lib, "ws2_32.lib") // fait gaffe, ce « #pragma » ne fonctionne qu'en C++(tu compile en C++ présentement, va dans la config et change ca pour une compilation en C) #include <winsock2.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h>
//#include <winbase.h> // <winsock2.h> inclut <windows.h> qui lui inclut <winbase.h> et d'autres fichiers
ton main() est ... bizarre ...
int main(int argc, char *argv[]) { if ( argc == 4) { struct config * conf = NULL; int nbrethread; int nthread; int portascanner; int scanip; portascanner = atoi(argv[1]); nbrethread = atoi(argv[2]); scanip = htonl(inet_addr(argv[3])); SetTimer(NULL,NULL,2000,NULL); // why? for (;;) { nthread = nbrethread; for (;nthread>0;nthread--) { // ici, tu as un malloc() mais sans free() plus bas ... Problème! // c'est dans ton main() que tu devrais faire appel a free() // et non dans le thread conf = (struct config *) malloc(sizeof(struct config) ); conf->ip = scanip; conf->port=portascanner; conf->hthread = CreateThread(NULL, 0, &connection, conf, 0, 0); CloseHandle(conf->hthread); // pourquoi fermes-tu le thread immédiatement après l'avoir créé??? portascanner++; } // Ca ce n'est pas bon, mais pas du tout ...
//ptite tempo de 2s entre chaque série de thread //GetMessage(&conf->msg,NULL,0,0); // si « conf->msg.message » ne vaut pas WM_TIMER // tu boucleras infiniment //while (conf->msg.message!=WM_TIMER) //{;;} while (GetMessage(&(conf->msg), NULL, 0, 0)) { if (conf->msg.message == WM_TIMER) { break; } } CloseHandle(conf->hthread); free(conf); // <<== } KillTimer(NULL,NULL); //return 0; } else { printf("Usage : scan.exe port_debut nthread ip\n"); //return 0; } return 0; }
pourquoi utilises-tu SetTimer()/GetMessage()/etc.? si tu veux faire une pause de X [milli]sec, utilise « VOID Sleep(DWORD dwMilliSec); »
Sleep( 2000 ); // aussi simple que ca ..
si tu veux lancer plusieurs threads avec différentes informations(struct config), utilise ceci:
#define MAX_THREAD MAXIMUM_WAIT_OBJECTS
HANDLE hThreads[MAX_THREAD]; struct config* confs = (struct config*)malloc(MAX_THREAD * sizeof(struct config));
for (i = 0; i < MAX_THREAD; i++) { confs[i].x = x_value; confs[i].y = y_value; confs[i].z = z_value; // etc.
hThreads[i] = CreateThread(NULL, 0, connection, &(confs[i]), 0, 0); }
// on attend les threads WaitForMultipleObjects(MAX_THREAD, hThreads, TRUE, INFINITE);
// fin des threads free(confs);
etc. etc. etc.
-=-= ExCRT =-=-
|
|
mercredi 5 juillet 2006 à 09:49:59 |
Re : problème avec WSAGetLastError()

fredo2009
|
Merci excrt , c vraiment un cours que tu m'as fait là.
pourquoi utilises-tu SetTimer()/GetMessage()/etc.? j'avais commencé par un Sleep(2000) et puis j'ai lu sur qques forum que Sleep avait tendance à endorpmir tous le programme. J'ai donc cherché autre chose pour faire une tempo. Mais finalement ça n change rien, je remet donc le Sleep.
#pragma comment(lib, "ws2_32.lib") // fait gaffe, ce « #pragma »..... En fait ce pragma ne me sert à rien vu que je compile sous dev. Il me suffit de rajouter ds l'editeur de lien -lwsock32. D'après ce que j'ai compris il aurait servi pour une compilation sous visual.
Enfin le prog commence à tourner un peu plus rond. Il fonctionne sans bug jusqu'à 10 thread simultannés. Au-delà, il ne détecte plus les connexions refusées mais seulement les connexions réussies.
|
|
Cette discussion est classée dans : port, code, connexion, sock, conf
Répondre à ce message
Sujets en rapport avec ce message
socket 100% CPU [ par fredo2009 ]
Salut@tousVoilà la fonction que j'utilise pour savoir si un port est ouvert sur une ip:DWORD WINAPI connection( LPVOID Param ) { struct config * conf
pb pr écouter sur un port... [ par Gendal67 ]
Bonsoir all...J'avais envie de créer une application utilisant les sockets liées à une connection TCP/IP qui écoute sur un port précis. Jusque là, pas
[FTP] Schema de fonctionnement [ par ZedMaTrix ]
Bonjours à tous !Bon je me fais ma petite classe FTP donc, et là je bloque un peu sur les commandes PORT et PASV.Y a un moment j'avais déjà tout codé
Erreur compilation, Requette pour Connaitre le premier port ouvert..... [ par wizard512 ]
Bonsoir,Je souhaiterais avoir un peu d'aide si possible,pour finir de réalisé un petit programme en c,Car j'ai rencontré des problè
probleme de send en C avec socket [ par thorn74 ]
bonjour je suis actuellement en IUT info et G un projet a faire mais je bloque je doit fair eun petit programme ou lorsqu'un ordinateur se connecte a
Connexion code C++ et Mysql [ par schadrac ]
Bonjour je voudrais savoir comment connecter mon code C++ et une base de données Mysql qui fonctionne sous Wampserver et qui est disponible sur tout
Probleme de conversion char int string... [ par pyr0123 ]
Salut, Je code un échange de trames (t'chat) par port série entre 2 PC en C++ .net VStudio 2k5. J'envoie la chaine 'toto' du PC1 vers PC2, avec l'hyp
connexion ftp c++ [ par Kyoshiro1501 ]
Bonjour tout le monde,j'ai besoin d'uploader un fichier sur un ftp en c++ (avec des commande simples)j'ai trouver une aide a cette adresse http://www.
Connexion serveur client réseau [ par matad0r ]
Bonjour ! Ceci est mon premier post ! Voilà mon problème : j'ai créer deux applications, une cliente et une serveur. Mais le problème est que elle ne
verification de code [ par dyroj ]
salut a tous,je voudrai savoir si il y a des faute au niveu de la fonction select() et si je suis obliger de metre sock+1 au lieu de sock dans se peti
Livres en rapport
|
Derniers Blogs
[TECHDAYS 2012] SESSION WEBMATRIX 2 : LE COUTEAU SUISSE GRATUIT POUR VOS DéVELOPPEMENTS WEB - SLIDES[TECHDAYS 2012] SESSION WEBMATRIX 2 : LE COUTEAU SUISSE GRATUIT POUR VOS DéVELOPPEMENTS WEB - SLIDES par gpommier
Suite à la session que j'ai présenté sur WebMatrix 2, vous pouvez trouver les slides ici, ainsi que les démos en packages nuget : démos1 et démos2 J'en profite pour remercier chaleureusement tous ceux qui sont venus très nombreux à cette sess...
Cliquez pour lire la suite de l'article par gpommier [SHAREPOINT] LES SESSIONS TECHDAYS 2012.[SHAREPOINT] LES SESSIONS TECHDAYS 2012. par Patrick Guimonet
Voici donc pour ceux qui n'ont pas pu venir, ou ceux qui n'ont pas pu toutes les suivre la liste des sessions SharePoint aux TechDays 2012, que je mettrais à jour dès que les liens des vidéo seront disponibles. Ou ici : http...
Cliquez pour lire la suite de l'article par Patrick Guimonet TECHDAYS PARIS 2012 : SESSION PLEINIèRE JOUR 3TECHDAYS PARIS 2012 : SESSION PLEINIèRE JOUR 3 par ROMELARD Fabrice
Speaker: Bernard Ourghanlian Cette session est comme chaque jour transmise en live par BrainSonic, et j'ai donc suivi cette troisième pleinière par ce moyen sur mon iPad . Elle est dédiée comme chaque année à la mise en perspective de l'é...
Cliquez pour lire la suite de l'article par ROMELARD Fabrice MISHRA READER : UN LECTEUR RSS TRèS ZUNE STYLE EN OPEN SOURCE !MISHRA READER : UN LECTEUR RSS TRèS ZUNE STYLE EN OPEN SOURCE ! par Vko
Hier durant une session dédiée aux Techdays 2012, j'ai eu le plaisir d'annoncer la sortie de la Béta 2 de Mishra Reader. C'est quoi ? Pour les utilisateurs, c'est une vraie expérience de lecture de flux RSS sur Windows. Rien à voir avec les produit...
Cliquez pour lire la suite de l'article par Vko [FRAMEWORK 4] LES TASKS ET LE THREAD UI[FRAMEWORK 4] LES TASKS ET LE THREAD UI par fathi
Je viens de passer quelques temps au TechDay's et j'ai pu voir pas mal de session intéressante. Par contre une chose m'a un peu étonné lors de certaines de ces sessions qui abordaient les améliorations du framework .NET (donc le 4.5) : en gros, bea...
Cliquez pour lire la suite de l'article par fathi
Forum
ALGORITHMESALGORITHMES par whayoub
Cliquez pour lire la suite par whayoub
Logiciels
Academy System (17.2.1.0)ACADEMY SYSTEM (17.2.1.0)Logiciel de gestion des établissements.
- élèves/étudiants (inscription, dossier, absence...)
-... Cliquez pour télécharger Academy System Easy-Planning (1.0.0.1)EASY-PLANNING (1.0.0.1)Basé sur les mêmes principes que MyPlanning, Easy-Planning permet de créer des plannings sous la ... Cliquez pour télécharger Easy-Planning COLLECTOR PLUS (3.00B)COLLECTOR PLUS (3.00B)COLLECTOR PLUS version 3.00B est un logiciel utilisant une base de données alimentée par :
- L... Cliquez pour télécharger COLLECTOR PLUS PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO (V7.4)PONAMEDIA TV DEVIENS HELLLOOO FLASH
LA TV SUR VOTRE ORDINATEUR.
Toute une plateforme Multi... Cliquez pour télécharger PONAMEDIA PREMIUM - HELLLOOO FLASH DEMO LettresFaciles 2011 (8.0.0.1)LETTRESFACILES 2011 (8.0.0.1)LettresFaciles est un logiciel facilitant la création et la rédaction de lettres types.
Son inte... Cliquez pour télécharger LettresFaciles 2011
|