我们在编写网络通信程序的时候,不论作为服务端还是客户端,常常需要确保实时检测与对方的连接状态,调用select函数监控文件描述符(套接字)的连接状态是最普遍的方法,但是当遇到对方断电或者网络线路突然断开的情况,select函数将接收不到来自对方的断开消息,所以维护着这一连接的文件描述符(套接字)已经没有存在的意义,这个时候往该文件描述符(套接字)内写内容依然不会返回错误,read也会堵塞着并不返回错误。因此也无法断定该套接字是否还处于连接状态,我们可以通过开启TCP的keepAlive选项来让TCP连接自身维护自己的连接状态,详见《Linux下回收异常断开的TCP连接》,但是倘若要及时检测网络连通性,不得不频繁地发心跳包,势必会影响通信带宽,不是很理想。 阅读全文
我们在实际应用中很可能遇到这样的情况:客户端与服务器之间已经建立了TCP长连接,他们之间正在进行数据通信,尚未主动执行close操作的时候,突然一方拔掉网线或者断电,双方会因为无法交互断开TCP连接的握手包而一直无法确认是否与对方断开连接。这个时候执行read或recvfrom操作会因为无法收到数据使得进程一直阻塞着而不会返回错误,write操作因为是向缓冲区内写数据,只要缓冲区未满则也不会返回错误。这样,异常断开的TCP连接所绑定的套接字(文件描述符)已经没有意义了,但仍然占用着一个位置,倘若不处理,无意义的套接字(文件描述符)累加到1024时,系统会因为无法再分配新的套接字(文件描述符)而无法接受新的TCP连接。 阅读全文