Bonjour,
J'essaie de faire un timeout sur un connect() pour un socket donné. Pour celà, je le passe en mode asynchrone le temps de la connexion et je gère le timeout à l'aide de la fonction select().
Voici ce que ça donne:
D'après MSDN, lorsque le socket est en mode non-bloquant, alors connect() renvoie WSAEWOULDBLOCK et l'opération continue. Donc pour savoir quand la connexion est faite, il suffit de placer un select() avec le timeout que l'on souhaite:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 // Mode non-bloquant fionbio = TRUE; ioctlsocket(s, FIONBIO, &fionbio); iRet = connect(s, (SOCKADDR *) &server, sizeof(server)); iLastError = WSAGetLastError(); // On repasse en mode bloquant fionbio = FALSE; ioctlsocket(s, FIONBIO, &fionbio); if (iRet == SOCKET_ERROR) { if (iLastError == WSAEWOULDBLOCK) { fd_set writefds; struct timeval tv; tv.tv_sec = 5; tv.tv_usec = 0; FD_ZERO(&writefds); FD_SET(s, &writefds); select(0, NULL, &writefds, NULL, &tv); if (FD_ISSET(s, &writefds)) { /* Traitement OK */ shutdown(s, SD_BOTH); } else { /* Traitement KO */ } } } closesocket(s);
Si le PC distant n'est pas connecté, alors la fonction accept() échoue au bout d'environ 20s. De plus, par défaut, sur Windows XP, on ne peut pas lancer plus de 10 connexions TCP simultannées.For connection-oriented, nonblocking sockets, it is often not possible to complete the connection immediately. In such a case, this function returns the error WSAEWOULDBLOCK. However, the operation proceeds. When the success or failure outcome becomes known, it may be reported in one of several ways depending on how the client registers for notification. If the client uses the select function, success is reported in the writefds set and failure is reported in the exceptfds set. If the client uses the functions WSAAsyncSelect or WSAEventSelect, the notification is announced with FD_CONNECT and the error code associated with the FD_CONNECT indicates either success or a specific reason for failure
Donc dans le cas d'une connexion qui échoue, lorsque le timeout est atteint, je souhaite fermer la connexion TCP afin de ne pas dépasser la limite. Or la fonction closesocket() n'a pas l'air suffisant, comme si la fonction connect() continuait à vouloir se connecter et garde la connexion TCP ouverte.
Pour tester, je lance dans des threads différents des tentatives de connexion au serveur. Je les lance par séries de 10, et une fois les 10 threads exécutés, j'en lance une nouvelle série. Parmi ces 10 threads, j'en mets un qui arrive à se connecter (thread 1), et 9 autres (threads 2 à 10) qui essaient de se connecter sur un serveur éteint (donc échec). La 1e série, le thread 1 arrive à se connecter tandis que dans les autres séries alors la plupart du temps il n'y arrive pas. Je pense donc que les connexion TCP ne sont pas correctement fermées.
Comment pourrais-je les fermer correctement? Est-ce une autre erreur?
Merci d'avance
Partager