Я разрабатываю фильтр источника RTSP на C ++ и использую WINSOCK 2.0 - блокирующий сокет.
Когда я создаю блокирующий сокет, я устанавливаю его SO_RCVTIMEO
на 3 секунд примерно так:
int ReceiveTimeout = 3000;
int e = setsockopt(Socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&ReceiveTimeout, sizeof(int));
Мой фильтр пытается подключиться к IP_ADDRESS: 554
(554 - это порт сервера RTSP). Если есть сервер, прослушивающий этот IP-адрес на порту 554, все идет хорошо, но:
Если мой фильтр создает сокет для существующего IP-адреса , но на случайном порту, который никто не слушает on, connect ()
ожидает 3 секунды и возвращает WSAETIMEDOUT
. Итак, через 3 секунды я знаю, что предоставленный URL неверен.
Если мой фильтр создает сокет для несуществующего IP-адреса и пытается подключить его, он зависает примерно на 10 секунд перед возвратом. ОШИБКА СОКЕТА. Итак, SO_RCVTIMEO
игнорируется, если IP-адрес не существует в сети ...
ВОПРОС: Как я могу установить тайм-аут для несуществующего IP во втором случае? Нужно ли мне сначала отправить ICMP PING, чтобы узнать, существует ли IP, или выполнить другую подобную проверку?
Любая помощь будет принята с благодарностью. Спасибо. :)
ОТВЕТ НА МОЮ ПРОБЛЕМУ
Поскольку я использую блокирующие сокеты, вызовите connect ()
блокирует, пока соединение не будет установлено, или соединение не будет установлено, потому что хост не отвечает, или он отказывается от подключения. Если я установлю тайм-аут сокета равным 3 секундам и попытаюсь подключиться к несуществующему хосту, мой компьютер (клиент) отправит TCP-пакет с установленным флагом SYN
, чтобы инициировать трехходовой рукопожатие . Обычно хост, если он включен, отвечает TCP-пакетом, содержащим установленные флаги ACK
и SYN
, а затем клиент (я) отправляет TCP-пакет с ACK
флаг установлен. Затем выполняется подключение. НО, если хост не работает и отправлено SYN
, клиент ждет, пока не истечет 3-секундный тайм-аут,а затем пытается СНОВА и СНОВА, пока не будет достигнута установка реестра TcpMaxConnectRetransmissions
( MICROSOFT ARTICLE ), потому что узел может работать, но пакет SYN
может получить потеряно ... В моей Windows XP этот параметр равен 4, я думаю, поэтому каждый раз, когда он пытается отправить SYN
, он ждет 3 секунды, а когда четвертая попытка не удалась, она возвращает SOCKET_ERROR
(через 12 секунд) и устанавливает WSAETIMEDOUT
в качестве последней ошибки WSA.
Для решения этой проблемы используются неблокирующие сокеты и попытки вручную измерить время попытки подключения (поскольку теперь connect ()
не будет блокировать), как предложил Мартин Джеймс.
Другой способ - возиться с реестром, что является последним средством ...