Не могу разобраться с грамотным закрытием Socket
От: Almair  
Дата: 20.03.07 09:37
Оценка:
Помогите. Хочу создать сканер диапазона ip по одному порту конкретному. Работать он конечно работает. Вот какая беда.
После 300-500 IP начинает говорить что все ip отвечают на FD_CONNECT

netstat показывает кучу соединений с ожиданием FIN_WAIT_1
и все...

Как от этого глюка избавиться??? Зарание спасибо...

Привожу часть кода программы непосредственно соединения.
Все это в тредах, порядка 20 тредов, пробовал в одном, не помогает.

среда Visual Studio 2005 MFC

библиотеки
#include <winsock2.h>
#include <ws2tcpip.h>



Код

WSADATA wsaData;
  int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
  if (iResult != NO_ERROR){
  return 1;
  }
    SOCKET ConnectSocket;
    ConnectSocket = INVALID_SOCKET;
    sockaddr_in clientService; 
    ZeroMemory( &clientService, sizeof(clientService) );
    
    if(ip[0][0]!='\0') 
    {
        clientService.sin_family = AF_INET;
        clientService.sin_addr.s_addr = inet_addr( (const char *)ip[0] );
        clientService.sin_port = htons(DEFAULT_PORT);
    }else{
       WSACleanup();    
       return 1;
    }

        ConnectSocket = socket(PF_INET, SOCK_STREAM, 0);
        if (ConnectSocket == INVALID_SOCKET) {
            WSACleanup();
            return 1;
        }




        u_long block = 1;
        if (ioctlsocket(ConnectSocket, FIONBIO, &block) == SOCKET_ERROR){
            return 1;
        }


        fd_set writefds;
        FD_ZERO(&writefds);
        FD_SET(ConnectSocket, &writefds);

        WSAAsyncSelect(ConnectSocket,my->GetSafeHwnd(),WM_USER+1,FD_CONNECT);
             WSAEVENT hEvent = WSACreateEvent(); 
        int flag = 1; 
        setsockopt (ConnectSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof (flag));        


    
        int rtt;
        rtt=connect(ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService));
        rtt=WSAGetLastError();
    while(1) 
    { 
        DWORD dwRet;
        if ((dwRet = WSAWaitForMultipleEvents(1, &hEvent, TRUE,500, TRUE)) == WSA_WAIT_FAILED){
        break;
        }

            if(dwRet == WSA_WAIT_TIMEOUT) 
            { 
            bad++;all++;
            WSAAsyncSelect( ConnectSocket, my->GetSafeHwnd(), 0, 0);
            break;
            } 
            WSANETWORKEVENTS events; 
            WSAEnumNetworkEvents(ConnectSocket, hEvent, &events); 

            if(events.lNetworkEvents & FD_CONNECT) 
            { 
            good++;all++;
            break;
            } 
    }

        shutdown(ConnectSocket, 2);
        closesocket(ConnectSocket);
        ConnectSocket=NULL;
        WSACleanup();
        WSACloseEvent(hEvent);
    return 0;


20.03.07 15:11: Перенесено модератором из 'C/C++' — Кодт
Re: Не могу разобраться с грамотным закрытием Socket
От: Garrett Россия  
Дата: 22.03.07 07:52
Оценка:
Здравствуйте, Almair, Вы писали:

A>Код

Прежде всего надо его в рабочий вид привести. Сейчас вообще непонятно почему он работает.
A>
A>WSADATA wsaData;
A>  int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
A>  if (iResult != NO_ERROR){
A>  return 1;
A>  }
A>    SOCKET ConnectSocket;
A>    ConnectSocket = INVALID_SOCKET;
A>    sockaddr_in clientService; 
A>    ZeroMemory( &clientService, sizeof(clientService) );
    
A>    if(ip[0][0]!='\0') 
A>    {
A>        clientService.sin_family = AF_INET;
A>        clientService.sin_addr.s_addr = inet_addr( (const char *)ip[0] );
A>        clientService.sin_port = htons(DEFAULT_PORT);
A>    }else{
A>       WSACleanup();    
A>       return 1;
A>    }

A>        ConnectSocket = socket(PF_INET, SOCK_STREAM, 0);
A>        if (ConnectSocket == INVALID_SOCKET) {
A>            WSACleanup();
A>            return 1;
A>        }




A>        u_long block = 1;
A>        if (ioctlsocket(ConnectSocket, FIONBIO, &block) == SOCKET_ERROR){
A>            return 1;
A>        }


A>        fd_set writefds;
A>        FD_ZERO(&writefds);
A>        FD_SET(ConnectSocket, &writefds);

A>        WSAAsyncSelect(ConnectSocket,my->GetSafeHwnd(),WM_USER+1,FD_CONNECT);// что такое my и как оно обрабатывает это сообщение?  
A>        WSAEVENT hEvent = WSACreateEvent(); 
A>        int flag = 1; 
A>        setsockopt (ConnectSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof (flag));        


    
A>        int rtt;
A>        rtt=connect(ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService));
A>        rtt=WSAGetLastError();
A>    while(1) 
A>    { 
A>        DWORD dwRet;
A>        if ((dwRet = WSAWaitForMultipleEvents(1, &hEvent, TRUE,500, TRUE)) == WSA_WAIT_FAILED){
A>        break;
A>        }

A>            if(dwRet == WSA_WAIT_TIMEOUT) 
A>            { 
A>            bad++;all++;
A>            WSAAsyncSelect( ConnectSocket, my->GetSafeHwnd(), 0, 0);
A>            break;
A>            } 
A>            WSANETWORKEVENTS events; 
A>            WSAEnumNetworkEvents(ConnectSocket, hEvent, &events); 

A>            if(events.lNetworkEvents & FD_CONNECT) 
A>            { 
A>            good++;all++;
A>            break;
A>            } 
A>    }

A>        shutdown(ConnectSocket, 2);
A>        closesocket(ConnectSocket);
A>        ConnectSocket=NULL;
A>        WSACleanup();
A>        WSACloseEvent(hEvent);
A>    return 0;
A>


WSAAsyncSelect привязывает событие сокета к оконному сообщению, а поток ждет какого-то левого не привязанного они к чему эвента.
в борьбе со здравым смыслом победа будет за нами!
Re: Не могу разобраться с грамотным закрытием Socket
От: Almair  
Дата: 22.03.07 11:27
Оценка:
Прошу прощения. Это строчка осталась только в памяти. Это были попытки реализовать через WSAAsyncSelect обработку сообщений. Потом отказался.
Сейчас реализовано через объект события. Поэтому эта строчка:

//WSAAsyncSelect(ConnectSocket,my->GetSafeHwnd(),WM_USER+1,FD_CONNECT);

Но от этого не легче.
Re[2]: Не могу разобраться с грамотным закрытием Socket
От: Garrett Россия  
Дата: 23.03.07 07:34
Оценка:
Здравствуйте, Almair, Вы писали:

A>Прошу прощения. Это строчка осталась только в памяти. Это были попытки реализовать через WSAAsyncSelect обработку сообщений. Потом отказался.

A>Сейчас реализовано через объект события. Поэтому эта строчка:

A>//WSAAsyncSelect(ConnectSocket,my->GetSafeHwnd(),WM_USER+1,FD_CONNECT);


A>Но от этого не легче.


WSAEventSelect не забыл?

Короче, давай рабочий код всего потока.
в борьбе со здравым смыслом победа будет за нами!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.