Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.224.38.3] |
|
Сообщ.
#1
,
|
|
|
Здравствуйте.
Меня интересует, можно ли для сокета, используемого в вызове connect() задать значение таймаута. Все дело в том, что мне нужно перебрать некоторое кол-во адресов в достаточно большой локальной сети, на предмет наличия по этим адресам некоторых открытых портов (сканирование). Если сервис отсутствует, то вызов connect() занимает уж больно продолжительный отрезок времени... Спасибо. |
Сообщ.
#2
,
|
|
|
Использую функцию select - самый быстрый вариант сканирования + использование потоков. Удачи!
|
Сообщ.
#3
,
|
|
|
Сообщ.
#4
,
|
|
|
Rara Avis, используй потоки или асинхронные сокеты.
|
Сообщ.
#5
,
|
|
|
Спасибо, про потоки я уже думал.
|
Сообщ.
#6
,
|
|
|
Rara Avis,
1. У вызова connect() в Windows нет конфигурированного таймаута. Он зашит в алгоритм TCP-модуля. В некоторых Unix-like системах это возможно. 2. Вам надо создать массив сокетов и запускать на отдельном сокете асинхронную функцию WSAConnect, используя модель с перекрытием - т.е. позапускать кучу коннектов и "бросить их на попечение системы". 3. Модель исполнения операций ввода/вывода с перекрытием (ее также называют моделью совмещенных операций) – Overlapped I/O. Она реализуется только на сокетах, которые при формировании были объявлены для исполнения на них совмещенных операций c помощью функции WSASocket(): SOCKET WSASocket( int af, int type, int protocol, LPWSAPROTOCOL_INFO lpProtocolInfo, GROUP g, DWORD dwFlags); Придется создать свои сообщения и привязать их к событию FD_CONNECT. Очень хорошо все это описано в книге Оланда (Olund) Оланд Д., Джонс Э. Программирование в сетях Microsoft Windows , ISBN: 5-318-00725-2 издательство "Питер", 2002, или в английской версии второго издания - Jones A., Ohlund J., Ohlund Jim Network Programming for Microsoft Windows, Second Edition Microsoft Press, February 13, 2002 ISBN: 0735615799, ее можно найти в Интернете? или пиринговых сетях в формате .chm. Завершение обработки ввода/вывода с перекрытием может выполняться двояким способом – или приложение ждет оповещения о возникновении сетевого события в event-объекте, или приложение обрабатывает сетевую ситуацию при помощи специальной "процедуры завершения", на которую указывает специальный параметр типа WSAOVERLAPPED_COMPLETION_ROUTINE. Этот параметр необязателен и представляет собой указатель на специальную функцию, которая вызывается после завершения нужной операции и обрабатывает ее данные. Для метода оповещения в помощью объектов-событий WinSock изменяет состояние данного объекта, ассоциированное о структурой WSAOVERLAPPED в "просигналенное", когда запрос на операцию ввода/вывода наконец завершится. Отслеживание этого момента приложение лучше производить при помощи функции WSAWaitForMultipleEvents(). Определив, что операция завершилась, надо определить и ее статус – успешное завершение или нет – с помощью функции WSAGetOverlappedResult(): BOOL WSAGetOverlappedResult( SOCKET sd, LPWSAOVERLAPPED lpOverlapped, LPDWORD lpcbTransfer, BOOL fWait, LPDWORD lpdwFlags ); Параметр lpOverlapped указывает на структуру WSAOVERLAPPED, определенную при инициировании операции. Параметр lpcbTransfer указывает на переменную, в которой фиксируется фактическое количество принятых или посланных байт. Параметр fWait определяет поведение функции – должна ли она ожидать, если операция на момент проверки еще не завершилась, или нет. При fWait=TRUE функция не вернет управление вплоть до завершения операции. При fWait=FALSE и еще продолжающейся операции функция возвращает FALSE с индикацией ошибки WSA_IO_INCOMPLETE. Так как в данном случае функция вызывается для уже "свершившегося" события, этот параметр не имеет последствий. Последний параметр lpdwFlags является указателем на переменную, в которую помещаются результирующие значения флагов, если вызов с перекрытием был выполнен функциями WSARecv() или WSARecvFrom(). При успешном завершении операции WSAGetOverlappedResult() возвращает TRUE. Если она возвращает FALSE, то: · Или I/O-операция еще выполняется. · Или I/O-операция завершилась, но с ошибками. · Или статус завершения I/O-операции не может быть определен из-за сопутствующих ошибок в параметрах WSAGetOverlappedResult(). Все это непросто, но - успехов! |
Сообщ.
#7
,
|
|
|
Огромное спасибо за столь подробный ответ. Удачи!
|
Сообщ.
#8
,
|
|
|
Привет, тема довольно старая но народ роеться в форуме, поэтому может кому пригодиться...
Я использую вместо стандартного connect свою обертку, тотже connect но последний параметр время ожидания int connectex(SOCKET s1, const struct sockaddr *name, int namelen, long timeout) { // As connect() but with timeout setting. int rc = 0; ULONG ulB; struct timeval Time; fd_set FdSet; ulB = TRUE; // Set socket to non-blocking mode ioctlsocket(s1, FIONBIO, &ulB); if (connect(s1, name, sizeof(SOCKADDR)) == SOCKET_ERROR) { if (WSAGetLastError() == WSAEWOULDBLOCK) { // now wait for the specified time FD_ZERO(&FdSet); FD_SET(s1, &FdSet); Time.tv_sec = timeout / 1000L; Time.tv_usec = (timeout % 1000) * 1000; rc = select(0, NULL, &FdSet, NULL, &Time); } } ulB = FALSE; // Restore socket to blocking mode ioctlsocket(s1, FIONBIO, &ulB); return (rc > 0) ? 0 : SOCKET_ERROR; } |
Сообщ.
#9
,
|
|
|
connectex пригодилась, спасибо )
|