Помогите. Хочу создать сканер диапазона 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++' — Кодт
Здравствуйте, 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 привязывает событие сокета к оконному сообщению, а поток ждет какого-то левого не привязанного они к чему эвента.
Прошу прощения. Это строчка осталась только в памяти. Это были попытки реализовать через WSAAsyncSelect обработку сообщений. Потом отказался.
Сейчас реализовано через объект события. Поэтому эта строчка:
//WSAAsyncSelect(ConnectSocket,my->GetSafeHwnd(),WM_USER+1,FD_CONNECT);
Но от этого не легче.