Я разрабатываю фильтр источника RTSP в С++, и я использую 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-адреса, но на случайном порту, который никто не слушает,
connect()
ждет 3 секунды и возвращаетWSAETIMEDOUT
. Итак, через 3 секунды я знаю, что предоставленный URL-адрес плох. -
Если мой фильтр создает сокет для не существующего IP-адреса и пытается его подключить, он висит около 10 секунд перед возвратом SOCKET_ERROR. Таким образом,
SO_RCVTIMEO
игнорируется, если IP не существует в сети...
Вопрос: Как установить тайм-аут для не существующего IP-адреса во втором случае? Нужно ли сначала отправлять ICMP PING, чтобы увидеть, существует ли IP-адрес или выполнить какую-либо другую проверку?
Любая помощь будет оценена. Thanx.:)
ОТВЕТ К МОЕЙ ПРОБЛЕМЕ
Поскольку я использую блокирующие сокеты, вызывайте блоки connect()
до тех пор, пока не будет установлено соединение, или соединение не будет выполнено, потому что хост не отвечает, или он отказывается от соединения. Если я установил тайм-аут сокета на 3 секунды и попытаюсь подключиться к хосту, который не существует, мой компьютер (клиент) отправит TCP-пакет с установленным флагом SYN
, чтобы инициировать рукопожатие Threeway. Обычно хост, если вверх, будет отвечать TCP-пакетом, содержащим флаги ACK
и SYN
, а затем клиент (я) отправит TCP-пакет с установленным флагом ACK
. Затем соединение выполняется. НО, если хост опущен и отправлен SYN
, клиент ждет, пока истечет 3-секундный тайм-аут, а затем попробует AGAIN и AGAIN, пока TcpMaxConnectRetransmissions
(MICROSOFT ARTICLE), поскольку хост может быть UP, но пакет SYN
может потеряться... Моя Windows XP имеет этот параметр в 4, я думаю, поэтому каждый раз, когда он пытается для отправки SYN
, он ждет 3 секунды, а когда четвертая попытка не удалась, он возвращает SOCKET_ERROR
(через 12 секунд) и устанавливает WSAETIMEDOUT
в качестве последней ошибки WSA.
Способ использования неблокирующих сокетов и попытка вручную измерить время попытки соединения (потому что теперь connect()
не будет блокироваться), как предположил Мартин Джеймс.
Еще один способ - возиться с реестром, который является последним средством...