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

Вниз

простенький сканер сети   Найти похожие ветки 

 
inex   (2007-03-06 12:34) [0]

Добрый день!
В приложении нужно реализовать простенький сканер сети (конкретно нужно найти хосты с неким открытым портом). Для этого я решил использовать ClientSocket. И тут возникла проблемка: при попытке активировать сокет на неработающий хост или несуществующий, программа очень долго ждет ответа.
Подскажите пожалуйста, где можно выставить таймаут.


 
Сергей М. ©   (2007-03-06 12:49) [1]

А ты к этому хосту обращаешься по имени или по адресу ?


 
SlymRO ©   (2007-03-06 13:10) [2]

Сканируй в несколько потоков...


 
inex   (2007-03-06 13:22) [3]


> А ты к этому хосту обращаешься по имени или по адресу ?

По адресу.


 
inex   (2007-03-06 13:26) [4]


> Сканируй в несколько потоков...

Скорость для меня особого значения не имеет, но уж очень долго программа ждет ответа.
Наверняка же где-то можно выставить таймаут!?


 
Сергей М. ©   (2007-03-06 13:26) [5]

Используй неблок.режим


 
inex   (2007-03-06 13:42) [6]


> Используй неблок.режим

Пробовал, но в этом случае по какой-то причине программа вообще ничего не ищет. Тоесть цикл проходит до конца а результата никакого.


 
Сергей М. ©   (2007-03-06 13:47) [7]

А ты вообще представляешь себе, что, как и почему происходит в компоненте в неблок.режиме ?


 
inex   (2007-03-06 14:21) [8]


> А ты вообще представляешь себе, что, как и почему происходит
> в компоненте в неблок.режиме ?

Есть цикл:

for i:=1 to 255 do
begin
ClientSocket.Host:="1.1.1."+ IntToStr(i);
ClientSocket.Open;
end;


После этого я обрабатываю события OnConnect и OnError.
Насколько я понимаю если установлен блокировочный режим, то компонент в данный момент времени может активировать только один сокет и поэтому цикл завмирает на операторе

ClientSocket.Open;


Если выставлен неблокировочный режим, компонент после выше приведенного оператора, не ждет ответа, а пытается открыть новый сокет.

Или я не прав?


 
Сергей М. ©   (2007-03-06 14:42) [9]


> компонент в данный момент времени может активировать только
> один сокет


Компонент в любом режиме активирует только один сокет.

Разница в том, что

- в блок.режиме вызов метода Open() (равносильно установке св-ва Active = True) управление будет возвращено либо после успешного установления коннекта (хост доступен, сервис активен, соединение акцептировано) либо возникнет исключение (либо хост недоступен, либо  сервис не активен, либо запрос на соединение отвержено сервисом)

- в неблок.режиме тот же вызов стартует операцию коннекта и немедленно возвращает управление, об успехе операции сообщит событие OnConnect, о неуспехе - OnError


 
inex   (2007-03-06 15:32) [10]

Сергей М., спасибо большое за информацию.

делаю так:

ClientSocket.Port:=21;
for i:=1 to 255 do
begin
ClientSocket.Host:="1.1.1."+ IntToStr(i);
ClientSocket.Open;
ClientSocket.Close;
end;

В событии OnConnect:

ListView1.Items.Add.Caption:=socket.RemoteHost;

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


 
Сергей М. ©   (2007-03-06 15:53) [11]


> в чем может быть ошибка.
>


В том что ты запустив операцию коннекта (Open) тут же ее прекращаешь(Close), не получив ни OnConnect (успех) ни OnError (отказ)


 
inex   (2007-03-06 16:05) [12]


> В том что ты запустив операцию коннекта (Open) тут же ее
> прекращаешь(Close), не получив ни OnConnect (успех) ни OnError
> (отказ)

Как же правильно поступить? Прописать Close в событии OnConnect? Прпобовал, результат тот же.


 
Сергей М. ©   (2007-03-06 16:11) [13]


> Прописать Close в событии OnConnect? Прпобовал, результат
> тот же


Так ты ж его, события OnConnect не дождался ?)

И, разумеется, не дождешься, если целевой хост и/или порт не доступен.


> Как же правильно поступить?


1. Стартуешь "таймер", отслеживающий нужные периоды.

2. Вызываешь Open и преспокойно продолжаешь заниматься своими скорбными делами.

2. В обработчике OnError фиксируешь факт недоступности хоста:сервиса и финализируешь таймер.

3. В обработчике OnConnect фиксируешь факт доступности хоста:сервиса и финализируешь таймер.


 
Сергей М. ©   (2007-03-06 16:56) [14]

4. В событии "тика таймера" отменяешь операцию коннекта вызовом Close().
Тик таймера и есть факт превышения допустимого таймаута ожидания события коннекта.


 
inex   (2007-03-06 16:56) [15]

Если после каждого открытия сокета я буду ждать событие OnConnect или OnError то получится то же самое что если бы я использовал блокировочный режим.
Неужели нету какого-то таймаута?


 
Сергей М. ©   (2007-03-06 16:56) [16]


> inex   (06.03.07 16:56) [15]


см. [14]


 
inex   (2007-03-06 17:07) [17]

Спасибо, Сергей М., за подсказку!!!

И как я сам не догадался!


 
G_M_S ©   (2007-03-07 11:37) [18]

Создай динамеческий (или статический) массив сокетов (можно рекордов соккет+таймер) - и получишь значительный прирост производительности.


 
Сергей М. ©   (2007-03-07 12:03) [19]


> можно рекордов соккет+таймер


На все сокеты достаточно одного таймера.


 
G_M_S ©   (2007-03-07 12:22) [20]


> На все сокеты достаточно одного таймера.

Все соккеты могу стартовать в разное время. Например: стоит ограничение на максимальное количество соккетов 60 шт, а надо просканить 1000 портов. Кто-то раньше завершил подключение (удачное), кто-то позже (неудачное, по таймеру). Зачем ждать? Только завершился - сразу новый таск.


 
Сергей М. ©   (2007-03-07 12:35) [21]


> G_M_S ©   (07.03.07 12:22) [20]


Ну и зачем куча таймеров-то ?

В обработчике одного и того же таймера работают счетчики таймаутов, ассоциированные каждый со своим гнездом.


 
G_M_S ©   (2007-03-12 10:08) [22]


> Ну и зачем куча таймеров-то ?

"Каждой твари - по таймеру"... так господь завещал.


> В обработчике одного и того же таймера работают счетчики
> таймаутов

А смысл? Если писать "на коленке" - то проще каждому сокету свой таймер дать (ИМХО проще ничего не бывает). А если мутить навороченно - то тогда надо создавать Thread с блокирующим сокетом, который будет выдавать куда-нить в массив результат своей работы и плодить уже потоки, а не сокеты. Это будет круче, но существенно геморойнее.



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

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

Наверх




Память: 0.52 MB
Время: 0.02 c
2-1192436477
thely
2007-10-15 12:21
2007.11.11
Написание простой OCX.


2-1192884365
user1024
2007-10-20 16:46
2007.11.11
Как записать значение типа Memo в таблицу БД?


15-1191398473
oxffff
2007-10-03 12:01
2007.11.11
Защита от Dameware mini control


2-1192460244
Dns
2007-10-15 18:57
2007.11.11
Как по Sender-y определить Родителя?


2-1192797770
Neo
2007-10-19 16:42
2007.11.11
поиск топ100