Форум: "Сети";
Текущий архив: 2007.11.11;
Скачать: [xml.tar.bz2];
Внизпростенький сканер сети Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.042 c