网络编程实战17 TCP并不总是可靠
TCP故障模式
感知TCP链路的方式有限,一种是read为核心的读操作,另一种是write为核心的写操作
无FIN包
网络中断:TCP感觉不到连接异常
●情况一:阻塞在read调用上,会一直阻塞下去,可以用超时来解决
●情况二:先调用write发送数据流,接下来阻塞在read上,结果会不同,TCP协议栈会不断尝试将发送缓冲区的数据发送出去,重传一定次数后,协议栈会标识该连接异常。阻塞的read会返回TIMEOUT的错误信息,如果程序还在往这条连接写数据,写操作会立即失败,返回SIGPIPE信号
系统崩溃:系统崩溃和杀死进程不同的地方在于,没有FIN包被发送出来。
●情况一:崩溃和网络中断类似
●情况二:崩溃之后又重启:重传的TCP分组到达重启后的系统,由于系统中没有该TCP分组对应的连接数据,会返回一个RST重置分节,TCP通过read或write可以对RST进行错误处理。
阻塞的read会返回Connection Reset错误,阻塞的write会返回一个SIGPIPE信号
有FIN包
对端有FIN包发出,可能是对端调用了close或shutdown显示关闭了连接,阻塞的read操作在完成正常接收的数据读取之后,FIN包会返回一个EOF来完成通知,此时read返回0(收到FIN相当于在接收缓冲区加了EOF,之前的有效数据不受影响,可以通过read返回值判断)
测试
read直接感知FIN包:杀死服务器,服务端发送FIN包,read返回了0,正常退出了客户端程序
write产生RST,read感知RST
向已关闭连接继续泻,导致SIGPIPE
第一次write,服务端无法查询到该TCP连接,发送RST给客户端。客户端第二次write会受到SIGPIPE信号,默认退出程序。
本文地址:https://blog.csdn.net/qq_36459662/article/details/107921017