![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
IP scanner
Art_Z © (2004-05-05 20:32:00)Как в Delphi5 просканить IP-диапозон и найти конкретный порт?
xShadow (2004-05-11 17:45:00) [1]
> Art_Z © (10.05.04 20:04) [26]
Аналога данной функции в NT подобных системах нет и небудет.
Art_Z (2004-05-10 20:04:00) [2]Плохо.А что там есть?(чтоб заменить эту функцию)
Art_Z (2004-05-10 20:04:00) [3]Плохо.А что там есть?(чтоб заменить эту функцию)
Polevi (2004-05-09 23:42:00) [4]обязана, ее там нет
Art_Z (2004-05-09 22:14:00) [5]Всё может быть...
А всё-таки может из-за неё прога в XP вылететь?
Polevi (2004-05-09 21:57:00) [6]> [21] Art_Z © (09.05.04 19:37)
слабое место у тебя в голове
Art_Z (2004-05-09 19:37:00) [7]Органам тоже! :)
У меня ещё вопрос,только не по сетям...
Функция RegisterServiceProcess из Kernel32.dll под WinXP нормально работает или с какими-нибудь ограниченьями или вообще неработает , а то у меня WinME-проверить никак немогу.
У меня прога работает безуперчно(отсылает на фоне письма, а в XP не катит, и единственное слабое место-эта функция.
Anatoly Podgoretsky (2004-05-09 12:28:00) [8]Art_Z © (08.05.04 20:13) [16]
Рукам и родителям волю не давай, только компетентным органам.
(2004-05-09 01:15:00) [9]Удалено модератором
Art_Z (2004-05-08 20:59:00) [10]А-а-а... :)
Verg (2004-05-08 20:14:00) [11]
> Что там до 12?
Ярмарка работает с 6 утра до 12 каждую субботу.
Art_Z (2004-05-08 20:13:00) [12]Весёлые вы ребята! :)
Спасибо.
В нашей деревенской билиотеке либо нормальные книги,но до 90-ого года издания.Либо чушь полная(разве что для местных учителей информатики).
В КОСК обязательно загляну!Что там до 12?
P.S.Дай волю моим родителям и они мой несчастный Celeron 266 разнесут кувалдой-уж очень им не нравиться моё увлечение.
Verg (2004-05-08 14:46:00) [13]
> Rouse_ © (08.05.04 12:44) [14]
Ок. Спасибо за замечание. Действительно недоглядел.
Сейчас исправим как должно быть:
function FindServer( const Network : string;
const NetMask : string;
Port : word;
TimeOut : integer) : string;
var
Addr:TSockAddr;
Fd, Fdr : PFdSet;
k, i: u_long;
Ki : integer;
TmVal:TTimeVal;
LastAddr,
StartAddr,
FinishAddr,
Mask : u_long;
SetSize : integer;
S : TSocket;
begin
Result := '';
StartAddr := ntohl(inet_addr(pchar(Network)));
Mask := ntohl(inet_addr(pchar(NetMask)));
if Mask <> u_long($FFFFFFFF) then
begin
StartAddr := (StartAddr and Mask) + 1;
FinishAddr := (StartAddr or not Mask) - 1;
end else
FinishAddr := StartAddr;
SetSize := (FinishAddr - StartAddr) + 1;
if SetSize <= 0 then
exit;
TmVal.tv_sec:=TimeOut;
TmVal.tv_usec:=0;
SetSize := SetSize*sizeof(Fd^.fd_array[0])+sizeof(Fd^.fd_count);
GetMem(Fd, SetSize);
GetMem(Fdr, SetSize);
try
ZeroMemory(@Addr, sizeof(Addr));
Addr.sin_family:=AF_INET;
Addr.sin_port:=htons(Port);
k:=1;
repeat
FD_ZERO(Fd^);
LastAddr := 0;
S := INVALID_SOCKET;
For i:=StartAddr to FinishAddr do
begin
if S<>INVALID_SOCKET then
closesocket(S);
S := socket(AF_INET, SOCK_STREAM, 0);
if S <> INVALID_SOCKET then
begin
if ioctlsocket(S, FIONBIO, k) <> SOCKET_ERROR then
begin
Addr.sin_addr.S_addr:=htonl(i);
if connect(S, Addr, SizeOf(Addr)) = SOCKET_ERROR then
begin
if WSAGetLastError = WSAENOBUFS then
begin
closeSocket(S);
LastAddr := i;
break
end;
if WSAGetLastError <> WSAEWOULDBLOCK then
continue;
end;
FD^.fd_array[FD^.fd_count] := S;
Inc(FD^.fd_count);
S:=INVALID_SOCKET;
end;
end;
end;
if Fd^.fd_count = 0 then exit;
Move(Fd^, Fdr^, SetSize);
select(FDr^.fd_count, nil, Fdr, nil, @TmVal);
For Ki := 0 to Fdr^.fd_count-1 do
begin
if (Result='') and FD_ISSET( FDr^.fd_array[Ki], Fd^ ) then
begin
I := sizeof(Addr);
if getpeername( FDr^.fd_array[Ki], Addr, I ) <> SOCKET_ERROR then
Result := inet_ntoa(Addr.sin_addr);
end;
end;
For Ki := 0 to Fd^.fd_count-1 do
closesocket(FD^.fd_array[Ki]);
StartAddr := LastAddr;
until (LastAddr = 0) or (Result <> '');
finally
FreeMem(Fd);
FreeMem(Fdr);
end;
end;
Так лучше? :)
Rouse_ (2004-05-08 12:44:00) [14]Занятная конструкция :)
> S := socket(AF_INET, SOCK_STREAM, 0);
> if (S <> INVALID_SOCKET) then
> begin
...
end
else
if WSAGetLastError = WSAENOBUFS then
LastAddr := i;
break;
Можно сказать наглядная демонстрация ошибки в реализации кода...
PS: Андрей, я понимаю что код не твой, но на такие вещи желательно сразу указыать...
Verg (2004-05-08 08:16:00) [15]
> Art_Z © (07.05.04 20:17) [11]
Приезжай в Е-бург на "яму" по субботам в КОСК "Россия" (что на ЖБИ). Там и литературы всякой и CD-шек недорогих. До 12-ти успевай, ага.
Я не думаю, что предки будут против, если ты будешь тратить деньги на хорошие книги для самообразования.
Alex Konshin (2004-05-07 21:28:00) [16]Библиотека?
Art_Z (2004-05-07 20:17:00) [17]Спасибо,Verg.Попробую разобраться во всём этом.
P.S.Где простому школьнику взять деньги на книги?У меня на и-нет с мобилой-то кое-как хватает,а хорошая литература нынче дорого стоит,а на позорную денег жалко.
Verg (2004-05-06 22:31:00) [18]Не, так не пойдет :)
Без второго PFDSet-та не получится. Будет утечка дескрипторов.
Надо еще один FDSET - рабочий, назовем его Fdr. Память под него надо выделять/освобождат синхронно с основным. Тогда соотв. кусок кода немного по-другому будет:
......
Move(Fd^, Fdr^, SetSize);
select(FDr^.fd_count, nil, Fdr, nil, @TmVal);
For Ki := 0 to Fdr^.fd_count-1 do
begin
if (Result='') and FD_ISSET( FDr^.fd_array[Ki], Fd^ ) then
begin
I := sizeof(Addr);
if getpeername( FDr^.fd_array[Ki], Addr, I ) <> SOCKET_ERROR then
Result := inet_ntoa(Addr.sin_addr);
end;
end;
For Ki := 0 to Fd^.fd_count-1 do
closesocket(FD^.fd_array[Ki]);
...............
Verg (2004-05-06 21:34:00) [19]Хм...
Еще одна ссылка была... почикалась случайно
http://www.zeiss.net.ru/docs/technol/tcpip/tcp00.htm
Verg (2004-05-06 21:13:00) [20]Про почитать - это тебе надо книжки почитать, оно лучше. Насчет ссылок:
http://book.itep.ru/7/sock_71.htm
http://www.mark-itt.ru/FWO/tcpip/
Теперь простой поисковик единственного сервера в подсети. В качестве наглядного примера для разбора (без претензий на идеальность):
uses ....., WinSock,....;
............
function FindServer( const Network : string; // Адрес подсети
const NetMask : string; // Маска подсти
Port : word; // Искомый порт
TimeOut : integer // Время ожидания в секундах
) : string;
var
Addr:TSockAddr;
Fd : PFdSet;
k, i: u_long;
Ki : integer;
TmVal:TTimeVal;
LastAddr,
StartAddr,
FinishAddr,
Mask : u_long;
SetSize : integer;
S : TSocket;
begin
Result := '';
StartAddr := ntohl(inet_addr(pchar(Network)));
Mask := ntohl(inet_addr(pchar(NetMask)));
if Mask <> u_long($FFFFFFFF) then
begin
StartAddr := (StartAddr and Mask) + 1;
FinishAddr := (StartAddr or not Mask) - 1;
end else
FinishAddr := StartAddr;
SetSize := (FinishAddr - StartAddr) + 1;
if SetSize <= 0 then
exit;
TmVal.tv_sec:=TimeOut;
TmVal.tv_usec:=0;
GetMem(Fd, SetSize*sizeof(Fd^.fd_array[0])+sizeof(Fd^.fd_count));
try
ZeroMemory(@Addr, sizeof(Addr));
Addr.sin_family:=AF_INET;
Addr.sin_port:=htons(Port);
k:=1;
repeat
FD_ZERO(Fd^);
LastAddr := 0;
For i:=StartAddr to FinishAddr do
begin
Addr.sin_addr.S_addr:=htonl(i);
S := socket(AF_INET, SOCK_STREAM, 0);
if (S <> INVALID_SOCKET) then
begin
if (ioctlsocket(S, FIONBIO, k) = SOCKET_ERROR)
or ( (connect(S, Addr, SizeOf(Addr)) = SOCKET_ERROR)
and (WSAGetLastError <> WSAEWOULDBLOCK)
) then
begin
closesocket( S );
end else
begin
FD.fd_array[FD^.fd_count] := S;
Inc(FD^.fd_count);
end;
end else
begin
if WSAGetLastError = WSAENOBUFS then
LastAddr := i;
break;
end;
end;
if Fd^.fd_count = 0 then exit;
select(FD^.fd_count, nil, Fd, nil, @TmVal);
For Ki := 0 to Fd^.fd_count-1 do
begin
if (Result='')
and FD_ISSET( FD^.fd_array[Ki], Fd^ ) then
begin
I := sizeof(Addr);
if getpeername( FD^.fd_array[Ki], Addr, I ) <> SOCKET_ERROR then
Result := inet_ntoa(Addr.sin_addr);
end;
closesocket(FD^.fd_array[Ki]);
end;
StartAddr := LastAddr;
until (LastAddr = 0) or (Result <> '');
finally
FreeMem(Fd);
end;
end;
Пример вызова:
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(FindServer('195.12.78.0', '255.255.255.0', 444, 5));
end;
Да, и про WSAStartup при старте приложения не забудь, а при завершении - про WSACleanup.