一.基本概念
(摘自:《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
End;