WINSOCK - 为非现有IP上的连接尝试设置超时?

Cip*_*ipi 17 c++ winsock2

我正在用C++开发一个RTSP源过滤器,我正在使用WINSOCK 2.0 - 阻塞套接字.

当我创建一个阻塞套接字时,我将其设置SO_RCVTIMEO为3秒,如下所示:

int ReceiveTimeout = 3000; 
int e = setsockopt(Socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&ReceiveTimeout, sizeof(int));
Run Code Online (Sandbox Code Playgroud)

我的过滤器尝试连接到IP_ADDRESS:554(554是RTSP服务器端口).如果有一台服务器在端口554上侦听该IP,一切顺利,但是:

  1. 如果我的过滤器创建了一个现有IP地址的套接字,但是在一个没有人监听的随机端口上,connect()等待3秒并返回WSAETIMEDOUT.所以在3秒后,我知道提供的URL很糟糕.

  2. 如果我的过滤器为非现有IP地址创建了一个套接字,并尝试连接它,它会在返回SOCKET_ERROR之前挂起大约10秒.因此,SO_RCVTIMEO如果网络上不存在IP ,则会被忽略...

问题: 在第二种情况下,如何设置非现有IP的超时?我是否需要首先发送ICMP PING以查看IP是否存在,或执行其他类似的检查?

任何帮助将不胜感激.感谢名单.:)

对我的问题的回答

因为我正在使用阻塞套接字,调用connect()块,直到建立连接,或连接失败,因为主机没有响应,或者它拒绝连接.如果我将套接字的超时设置为3秒,并尝试连接到不存在的主机,我的PC(客户端)将发送带有SYN标志设置的TCP数据包,以启动Threeway握手.通常,主机(如果启动)将使用包含ACKSYN设置标志的TCP数据包进行响应,然后,客户端(我)将发送带有ACK标志设置的TCP数据包.然后建立连接.但是,如果主机关闭,并且SYN被发送,客户等待3秒超时,然后再次尝试,又一次,直到TcpMaxConnectRetransmissions(Microsoft文章达到)注册表设置,因为主机可以UP,但SYN数据包可能迷路...我的Windows XP将此设置为4,我猜,所以每次尝试发送时SYN,等待3秒,当第四次尝试失败时,它返回SOCKET_ERROR(12秒后),并设置WSAETIMEDOUT为最后一次WSA错误.

解决这个问题的方法是使用非阻塞套接字,并尝试手动测量连接尝试时间(因为现在connect()不会阻塞),就像Martin James所说的那样.

另一种方法是摆弄注册表,这是最后的手段......

Mar*_*mes 2

硬着头皮。远程 IP 可能没有运行 PING 服务器,或者 PING 可能被某些路由器阻止,因此没有帮助。您能不能只等待 10 秒,然后做出您使用的任何错误指示?

如果您绝对必须在 3 秒后尝试连接超时,您可以自行超时。

  • 我得到了 ping 捕获,但我怎样才能自己超时呢?当套接字仍在尝试连接时,如何阻止另一个线程的连接尝试?我需要 `connect()` 函数返回,这样我才能有一个工作的可断开套接字。还是我错了? (3认同)