![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
простенький сканер сети
inex © (2007-03-06 12:34:00)Добрый день!
В приложении нужно реализовать простенький сканер сети (конкретно нужно найти хосты с неким открытым портом). Для этого я решил использовать ClientSocket. И тут возникла проблемка: при попытке активировать сокет на неработающий хост или несуществующий, программа очень долго ждет ответа.
Подскажите пожалуйста, где можно выставить таймаут.
G_M_S (2007-03-12 10:08:00) [1]
> Ну и зачем куча таймеров-то ?
"Каждой твари - по таймеру"... так господь завещал.
> В обработчике одного и того же таймера работают счетчики
> таймаутов
А смысл? Если писать "на коленке" - то проще каждому сокету свой таймер дать (ИМХО проще ничего не бывает). А если мутить навороченно - то тогда надо создавать Thread с блокирующим сокетом, который будет выдавать куда-нить в массив результат своей работы и плодить уже потоки, а не сокеты. Это будет круче, но существенно геморойнее.
Сергей М. (2007-03-07 12:35:00) [2]
> G_M_S © (07.03.07 12:22) [20]
Ну и зачем куча таймеров-то ?
В обработчике одного и того же таймера работают счетчики таймаутов, ассоциированные каждый со своим гнездом.
G_M_S (2007-03-07 12:22:00) [3]
> На все сокеты достаточно одного таймера.
Все соккеты могу стартовать в разное время. Например: стоит ограничение на максимальное количество соккетов 60 шт, а надо просканить 1000 портов. Кто-то раньше завершил подключение (удачное), кто-то позже (неудачное, по таймеру). Зачем ждать? Только завершился - сразу новый таск.
Сергей М. (2007-03-07 12:03:00) [4]
> можно рекордов соккет+таймер
На все сокеты достаточно одного таймера.
G_M_S (2007-03-07 11:37:00) [5]Создай динамеческий (или статический) массив сокетов (можно рекордов соккет+таймер) - и получишь значительный прирост производительности.
inex (2007-03-06 17:07:00) [6]Спасибо, Сергей М., за подсказку!!!
И как я сам не догадался!
Сергей М. (2007-03-06 16:56:00) [7]
> inex (06.03.07 16:56) [15]
см. [14]
inex (2007-03-06 16:56:00) [8]Если после каждого открытия сокета я буду ждать событие OnConnect или OnError то получится то же самое что если бы я использовал блокировочный режим.
Неужели нету какого-то таймаута?
Сергей М. (2007-03-06 16:56:00) [9]4. В событии "тика таймера" отменяешь операцию коннекта вызовом Close().
Тик таймера и есть факт превышения допустимого таймаута ожидания события коннекта.
Сергей М. (2007-03-06 16:11:00) [10]
> Прописать Close в событии OnConnect? Прпобовал, результат
> тот же
Так ты ж его, события OnConnect не дождался ?)
И, разумеется, не дождешься, если целевой хост и/или порт не доступен.
> Как же правильно поступить?
1. Стартуешь "таймер", отслеживающий нужные периоды.
2. Вызываешь Open и преспокойно продолжаешь заниматься своими скорбными делами.
2. В обработчике OnError фиксируешь факт недоступности хоста:сервиса и финализируешь таймер.
3. В обработчике OnConnect фиксируешь факт доступности хоста:сервиса и финализируешь таймер.
inex (2007-03-06 16:05:00) [11]
> В том что ты запустив операцию коннекта (Open) тут же ее
> прекращаешь(Close), не получив ни OnConnect (успех) ни OnError
> (отказ)
Как же правильно поступить? Прописать Close в событии OnConnect? Прпобовал, результат тот же.
Сергей М. (2007-03-06 15:53:00) [12]
> в чем может быть ошибка.
>
В том что ты запустив операцию коннекта (Open) тут же ее прекращаешь(Close), не получив ни OnConnect (успех) ни OnError (отказ)
inex (2007-03-06 15:32:00) [13]Сергей М., спасибо большое за информацию.
делаю так:
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 14:42:00) [14]
> компонент в данный момент времени может активировать только
> один сокет
Компонент в любомрежиме активирует только одинсокет.
Разница в том, что
- в блок.режиме вызов метода Open() (равносильно установке св-ва Active = True) управление будет возвращено либо после успешного установления коннекта (хост доступен, сервис активен, соединение акцептировано) либо возникнет исключение (либо хост недоступен, либо сервис не активен, либо запрос на соединение отвержено сервисом)
- в неблок.режиме тот же вызов стартует операцию коннекта и немедленно возвращает управление, об успехе операции сообщит событие OnConnect, о неуспехе - OnError
inex (2007-03-06 14:21:00) [15]
> А ты вообще представляешь себе, что, как и почему происходит
> в компоненте в неблок.режиме ?
Есть цикл:
for i:=1 to 255 do
begin
ClientSocket.Host:='1.1.1.'+ IntToStr(i);
ClientSocket.Open;
end;
После этого я обрабатываю события OnConnect и OnError.
Насколько я понимаю если установлен блокировочный режим, то компонент в данный момент времени может активировать только один сокет и поэтому цикл завмирает на операторе
ClientSocket.Open;
Если выставлен неблокировочный режим, компонент после выше приведенного оператора, не ждет ответа, а пытается открыть новый сокет.
Или я не прав?
Сергей М. (2007-03-06 13:47:00) [16]А ты вообще представляешь себе, что, как и почему происходит в компоненте в неблок.режиме ?
inex (2007-03-06 13:42:00) [17]
> Используй неблок.режим
Пробовал, но в этом случае по какой-то причине программа вообще ничего не ищет. Тоесть цикл проходит до конца а результата никакого.
Сергей М. (2007-03-06 13:26:00) [18]Используй неблок.режим
inex (2007-03-06 13:26:00) [19]
> Сканируй в несколько потоков...
Скорость для меня особого значения не имеет, но уж очень долго программа ждет ответа.
Наверняка же где-то можно выставить таймаут!?
inex (2007-03-06 13:22:00) [20]
> А ты к этому хосту обращаешься по имени или по адресу ?
По адресу.