Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.07.04;
Скачать: CL | DM;

Вниз

IP scanner   Найти похожие ветки 

 
Art_Z ©   (2004-05-05 20:32) [0]

Как в Delphi5 просканить IP-диапозон и найти конкретный порт?


 
Rouse_ ©   (2004-05-05 20:37) [1]

Какой диапазон? Какой именно порт? Параметры соответствия? Тип сети?


 
Art_Z ©   (2004-05-05 20:53) [2]

Есть локальная сеть.В локальной сети сервер с открытым портом X.Конкретный IP-адрес сервера мы не знаем, но знаем в каком диапозоне лежат адреса данной сетки.Нам нужно найти этот порт X в сети.На этом мои знания дилетанта заканчиваються... :)


 
Rouse_ ©   (2004-05-05 23:24) [3]

Итого:
> В локальной сети сервер с открытым портом X - Порт стало быть не известен?

> Конкретный IP-адрес сервера мы не знаем, но знаем в каком
> диапозоне лежат адреса данной сетки.

Каков же диапазон?

> Нам нужно найти этот порт X в сети.
Как ты его найдешь, по какому признаку?

Ну а теперь немного конкретики, и плз, ответь нормально...
1. Сеть одноранговая или доменная?
2. По какому признаку и вообще что за порт ты пыташься найти, сам порт известен?
3. Диапазон наводит на мысль о разветвлении маски подсети, оно?


 
Polevi ©   (2004-05-06 08:00) [4]

в цикле


 
Art_Z ©   (2004-05-06 20:16) [5]

Порт известен.Сеть одноранговая.Диапозон(если я тебя правельно понял) выглядит так XXX.XXX.XXX.1-255


 
Verg ©   (2004-05-06 20:25) [6]


> Art_Z ©   (06.05.04 20:16) [5]


Допустим речь идет про TCP порт (угадайка нынче в моде, видимо :)) Допустим сервер - это не "наше" приложение, которое бы мы могли снабдить UDP службой, откликающейся на широковещательные запросы типа "где ты?!"

Тогда надо попробовать подключиться к каждому адресу на заданный порт и, если соединение прошло успешно, то этот адрес обслуживает данный порт.
Делать это можно либо последовательно, т.е. одним сокетом, либо параллельно, т.е. несколькими в целях ускорения процесса.
Тогда возникает вопрос: а как планируется - "до первого успеха" или нужны все адреса из диапазона, обслуживающие данный порт?


 
Art_Z ©   (2004-05-06 20:41) [7]

Порт в сетке всего один.Приложение наше,но так как я вообщем-то делитант,то об UDP и широковещательных запросах слышал толко от таких опытных людей,как вы.Если будет не жалко времени,то можете объяснить неучу что это такое или дать ссылку где об этом можно почитать...


 
Verg ©   (2004-05-06 21:13) [8]

Про почитать - это тебе надо книжки почитать, оно лучше. Насчет ссылок:

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.


 
Verg ©   (2004-05-06 21:34) [9]

Хм...
Еще одна ссылка была... почикалась случайно

http://www.zeiss.net.ru/docs/technol/tcpip/tcp00.htm


 
Verg ©   (2004-05-06 22:31) [10]

Не, так не пойдет :)
Без второго 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]);
...............


 
Art_Z ©   (2004-05-07 20:17) [11]

Спасибо,Verg.Попробую разобраться во всём этом.

P.S.Где простому школьнику взять деньги на книги?У меня на и-нет с мобилой-то кое-как хватает,а хорошая литература нынче дорого стоит,а на позорную денег жалко.


 
Alex Konshin ©   (2004-05-07 21:28) [12]

Библиотека?


 
Verg ©   (2004-05-08 08:16) [13]


> Art_Z ©   (07.05.04 20:17) [11]


Приезжай в Е-бург на "яму" по субботам в КОСК "Россия" (что на ЖБИ). Там и литературы всякой и CD-шек недорогих. До 12-ти успевай, ага.
Я не думаю, что предки будут против, если ты будешь тратить деньги на хорошие книги для самообразования.


 
Rouse_ ©   (2004-05-08 12:44) [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 14:46) [15]


> 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;


Так лучше? :)


 
Art_Z ©   (2004-05-08 20:13) [16]

Весёлые вы ребята! :)
Спасибо.
В нашей деревенской билиотеке либо нормальные книги,но до 90-ого года издания.Либо чушь полная(разве что для местных учителей информатики).
В КОСК обязательно загляну!Что там до 12?
P.S.Дай волю моим родителям и они мой несчастный Celeron 266 разнесут кувалдой-уж очень им не нравиться моё увлечение.


 
Verg ©   (2004-05-08 20:14) [17]


> Что там до 12?


Ярмарка работает с 6 утра до 12 каждую субботу.


 
Art_Z ©   (2004-05-08 20:59) [18]

А-а-а... :)


 
имя   (2004-05-09 01:15) [19]

Удалено модератором


 
Anatoly Podgoretsky ©   (2004-05-09 12:28) [20]

Art_Z ©   (08.05.04 20:13) [16]
Рукам и родителям волю не давай, только компетентным органам.


 
Art_Z ©   (2004-05-09 19:37) [21]

Органам тоже! :)
У меня ещё вопрос,только не по сетям...
Функция RegisterServiceProcess из Kernel32.dll под WinXP нормально работает или с какими-нибудь ограниченьями или вообще неработает , а то у меня WinME-проверить никак немогу.
У меня прога работает безуперчно(отсылает на фоне письма, а в XP не катит, и единственное слабое место-эта функция.


 
Polevi ©   (2004-05-09 21:57) [22]

> [21] Art_Z ©   (09.05.04 19:37)
слабое место у тебя в голове


 
Art_Z ©   (2004-05-09 22:14) [23]

Всё может быть...
А всё-таки может из-за неё прога в XP вылететь?


 
Polevi ©   (2004-05-09 23:42) [24]

обязана, ее там нет


 
Art_Z ©   (2004-05-10 20:04) [25]

Плохо.А что там есть?(чтоб заменить эту функцию)


 
Art_Z ©   (2004-05-10 20:04) [26]

Плохо.А что там есть?(чтоб заменить эту функцию)


 
xShadow ©   (2004-05-11 17:45) [27]


> Art_Z ©   (10.05.04 20:04) [26]

Аналога данной функции в NT подобных системах нет и небудет.



Страницы: 1 вся ветка

Текущий архив: 2004.07.04;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.033 c
3-1085681089
U96
2004-05-27 22:04
2004.07.04
UpdateSQL


14-1087497218
KilkennyCat
2004-06-17 22:33
2004.07.04
Калеки! Т.е., коллеги! У кого есть "Мазда", "Сузуки", "Тойота"?


3-1086285323
hardclubber
2004-06-03 21:55
2004.07.04
Ошибка с кодировками


14-1087166444
Mobias
2004-06-14 02:40
2004.07.04
???


1-1087399722
snake1977
2004-06-16 19:28
2004.07.04
Поиск по документам Word