一.基本概念(摘自:《unix网络编程》卷1 14.2 套接字超时)
在涉及套接字的I/O操作上设置超时的方法有以下三种
(1)调用alarm,它在指定超时期满时产生SIGALARM。这个方法涉及信号处理,而信号处理在不同的实现上存在差异,而且可能干扰进程中现有的alarm调用。
(2)在select中阻塞等待I/O(select有内置的时间限制),以此替代直接阻塞在read或write调用上。
(3)使用SO_RECVTIMEO和SO_SNDTIMEO套接字选项
上述三个技术都适用于输入输出操作(例如read、write及其诸如recvfrom、sendto之类的变体),不过我们依然期待可用于connect的技术,因为TCP内置的connect超时相当长(典型值为75秒钟)。select可用来在connect上设置超时的先决条件是相应的套接字是处于非阻塞模式,而那两个套接字选项对connect并不适用。我们还指出,前两个技术适用于任何描述符,而第三个技术仅仅适用于套接字描述符。
二.非阻塞模式socket
1.connect不需要考虑超时问题,立即返回一个错误EINPROGRESS,可通过检测fd是否可用判断连接是否建立完成
2.read不需要考虑超时问题,立即返回
3.write不需要考虑超时问题,立即返回
三.阻塞模式socket
1.connect需要考虑超时问题,否则当连接IP不可达的情况下,需要等待很长一段时间(默认时长)
2.read需要考虑超时问题,可通过setsockopt设置SO_RECVTIMEO选项
3.write需要考虑超时问题,可通过setsockopt设置SO_SNDTIMEO选项
在涉及套接字的I/O操作上设置超时的方法有以下三种
(1)调用alarm,它在指定超时期满时产生SIGALARM。这个方法涉及信号处理,而信号处理在不同的实现上存在差异,而且可能干扰进程中现有的alarm调用。
(2)在select中阻塞等待I/O(select有内置的时间限制),以此替代直接阻塞在read或write调用上。
(3)使用SO_RECVTIMEO和SO_SNDTIMEO套接字选项
上述三个技术都适用于输入输出操作(例如read、write及其诸如recvfrom、sendto之类的变体),不过我们依然期待可用于connect的技术,因为TCP内置的connect超时相当长(典型值为75秒钟)。select可用来在connect上设置超时的先决条件是相应的套接字是处于非阻塞模式,而那两个套接字选项对connect并不适用。我们还指出,前两个技术适用于任何描述符,而第三个技术仅仅适用于套接字描述符。
注:阻塞模式下,当服务器连接不上时,通过命令 “netstat -tlnap|grep SENT" 可以看到客户端会处于SYN_SENT状态,直到connect超时
二.非阻塞模式socket
1.connect不需要考虑超时问题,立即返回一个错误EINPROGRESS,可通过检测fd是否可用判断连接是否建立完成
2.read不需要考虑超时问题,立即返回
3.write不需要考虑超时问题,立即返回
三.阻塞模式socket
1.connect需要考虑超时问题,否则当连接IP不可达的情况下,需要等待很长一段时间(默认时长)
2.read需要考虑超时问题,可通过setsockopt设置SO_RECVTIMEO选项
3.write需要考虑超时问题,可通过setsockopt设置SO_SNDTIMEO选项
四.带超时的connect,适用于阻塞模式与非阻塞模式socket(本质上是非阻塞connect)
附上测试代码,可通过更改main中的IP和端口进行测试,读懂这段代码需要了解select与getsockopt函数
----- g++ connect_nonb.cpp -----
参考:《unix网络编程》卷1