Переделываю сканер диапазона IP на открытый определённый порт с С (от kaht2) на Delphi и столкнулся с несколькими проблемами.  1) Там используется несколько потоков, IP который нужно проверить выдёт функция GiveMyIp, при одновременном обращении к ней из разных потоков она может выдать один и тотже IP. 2) Самое главное, при скане перестаёт работать инет т.е. скан работает а сайт неодин негрузится даже после остановки скана, пока неперегрузишся всё перестаёт работать. Исходник ниже. | Код | program Project2;
{$APPTYPE CONSOLE}
uses Windows, sysutils, Messages, Classes, WinSock2;
type TMyScan = class(TThread)
public procedure Execute; override; end;
var MScaner:TMyScan; i:integer; thead:integer; addr : TSockAddr; fset : TFDset; tv : TTimeval; GInitData : TWSADATA; temp:string; StartIP:String; StartIPaddr:array[1..4] of integer;
//-------------------------------------------> // Возвращает ип который нужно проверить //-------------------------------------------> function GiveMyIp:string; begin if (StartIpaddr[4]<>254) then StartIpaddr[4]:=StartIpaddr[4]+1 else begin if StartIpaddr[3]<=254 then begin StartIpaddr[3]:=StartIpaddr[3]+1; StartIpaddr[4]:=1; writeln(IntToStr(StartIpaddr[1])+'.'+IntToStr(StartIpaddr[2])+ '.'+IntToStr(StartIpaddr[3])+'.'+IntToStr(StartIpaddr[4])); end else begin GiveMyIp:='0'; Exit; end; end; GiveMyIp:=IntToStr(StartIpaddr[1])+'.'+IntToStr(StartIpaddr[2])+ '.'+IntToStr(StartIpaddr[3])+'.'+IntToStr(StartIpaddr[4]);
end;
//-------------------------------------------> // Сам сканер //-------------------------------------------> procedure TMyScan.execute; var ssock:integer; on_sock :U_LONG; IPTmp:string; j:integer; begin thead:=thead+1; //увеличим счетчик потоков на 1 sleep(1);
while (IPTmp<>'0') do begin // IPTmp:=GiveMyIp; // запрашиваем ип который нужно проверить
addr.sin_family := AF_INET; addr.sin_addr.S_addr :=inet_addr(Pchar(IPTmp)); addr.sin_port := htons(135); closesocket(ssock);
ssock:=socket(AF_INET,SOCK_STREAM,0); if ssock<> -1 then begin on_sock:=1; ioctlsocket(ssock,FIONBIO,on_sock); tv.tv_sec:=6; tv.tv_usec:=0; FD_ZERO(fset); FD_SET (ssock, fset); connect(ssock, @addr, sizeof(addr)); j:= select(ssock+1,nil,@fset,nil,@tv); if j>0 then //если подключились begin writeln(IPTmp); //выведем найденое(программа консольная) sleep(1); end; end; closesocket(ssock);
end;
thead:=thead-1; Sleep(1); MScaner.Terminate; end;
//-------------------------------------------> // отсюда идёт запуск потоков //-------------------------------------------> procedure MyScanr(ScanDiap:string;total:integer); var ss:integer; begin
// разбираем IP вида '127.0.0.1' в массив temp:=ScanDiap; temp:=temp + '.'; for ss:=1 to 4 do begin StartIPaddr[ss]:=strtoint(copy(temp,1,pos('.',temp) - 1)); delete(temp,1,pos('.',temp)); end;
total:=40; // количество потков тут безразницы стоит 1 или 255 // инет всё равно перестаёт работать thead:=0; for ss:=0 to total do begin
MScaner:=TMyScan.Create(true); MScaner.Priority:=tpLower; MScaner.Resume; end; while(thead>0) do //пока есть запущеные потки подождём sleep(100);
end;
//-------------------------------------------> // Старт программы //-------------------------------------------> begin
WSAStartup(MAKEWORD(2,0), GInitData);
StartIp:='195.85.0.1'; MyScanr(StartIp,5); Sleep(60000);
WSACleanup;
end.
|
Вобщем надеюсь на помощь.
|