面试题答案
一键面试在非阻塞I/O模型下,检测网络连接故障可从以下方面着手:
1. send
系统调用
- 返回值含义:
- 成功时,
send
返回实际发送的字节数。若返回值等于期望发送的字节数,说明数据成功发送出去。 - 若返回值小于期望发送的字节数,且
errno
设置为EAGAIN
或EWOULDBLOCK
,这意味着当前没有足够的缓冲区空间立即发送所有数据,但连接可能正常,后续可再次尝试发送。 - 若返回值为 -1,且
errno
为ECONNRESET
,表示对方已重置连接,这是一种常见的连接故障,可能是对方异常关闭或网络问题导致连接被重置。 - 若
errno
为EPIPE
,表示管道破裂,通常是因为对方关闭了连接,而本地还在尝试向已关闭的连接发送数据。
- 成功时,
2. recv
系统调用
- 返回值含义:
- 成功时,
recv
返回接收到的字节数。若返回0,说明对方已关闭连接(正常关闭)。 - 若返回 -1,且
errno
为EAGAIN
或EWOULDBLOCK
,表明当前没有数据可读,但连接可能正常,后续可再次尝试接收。 - 若
errno
为ECONNREFUSED
,表示连接被拒绝,通常是因为目标端口未监听或防火墙阻止连接,这意味着连接建立阶段就出现故障。 - 若
errno
为ECONNRESET
,同send
中的情况,说明对方重置了连接,连接存在故障。
- 成功时,
3. select
、poll
或epoll
等多路复用系统调用
- 使用方式及含义:
- 这些系统调用可以监视多个文件描述符(包括套接字)的状态变化。以
select
为例,通过设置读、写和异常事件掩码来等待文件描述符状态改变。 - 当一个套接字在
select
的读集合中就绪时(返回值大于0且对应文件描述符在读集合),调用recv
接收数据。若recv
返回0,说明对方关闭连接;若recv
返回 -1 且为上述连接故障相关的errno
值,可判断连接故障。 - 当套接字在写集合中就绪时(同样
select
返回值大于0且在写集合),调用send
发送数据,根据send
返回值判断连接是否存在故障。若select
返回值为0,表示在指定时间内没有任何文件描述符就绪,可适当延长等待时间再次尝试。若select
返回 -1,且errno
不是EINTR
(表示系统调用被信号中断,可重新调用),则可能存在系统错误影响连接检测。
- 这些系统调用可以监视多个文件描述符(包括套接字)的状态变化。以
4. getsockopt
系统调用
- 使用方式及含义:
- 可通过
getsockopt
获取套接字的一些选项信息来检测连接状态。例如,获取SO_ERROR
选项,该选项返回与套接字关联的待处理错误。 - 若
getsockopt
获取到的SO_ERROR
值为0,表示套接字当前没有错误,连接可能正常。若获取到非0值,可根据具体错误码判断连接故障类型,如非0值为ECONNRESET
等上述提到的连接故障错误码,即可判断连接出现相应故障。
- 可通过