TCP异常与处理

为君一笑 提交于 2020-03-07 10:51:40

TCP中出现的错误及处理

首先要明确,TCP连接关闭有两种方法其一是正常的四次挥手,会经历多个状态,最后连接正常关闭,还有一种方法是连接异常关闭,即此时对方希望连接能够尽快关闭,发送RST包后连接会直接关闭,不会再出现上述的状态转换

进程正常关闭/进程被杀死/服务器重启
  1. 这三种情况下,服务器关闭套接字,并发起第一次挥手操作,客户端收到FIN包,并返回ack,
  2. 此时连接处于半关闭状态,客户端并不知道服务器已经关闭,客户端如果继续向服务器write数据,那么服务器会向客户端发送RST包,
  3. 当客户端收到RST包时,如果再write,那么将返回EPIPE错误,同时会导致SIGPIPE信号,如果从收到RST包的连接上read,那么将返回ECONNRESET错误
  4. 如果客户端是使用的select/epoll等,那么当select/epoll收到RST会返回连接可读,即调用read返回ECONNRESET错误(但是根据muduo库测试最后epoll收到RST后返回可读,但是read会返回0,此处存疑),注意这里所说的错误是errno的值,同时也是套接字的待处理错误,所以此时调用getsockopt所获得的error是相应的错误,epoll/select所监视的某个socket上如果出现了错误,那么将会返回可读可写
服务器崩溃/服务器不可达
  1. 服务器崩溃时,如果有数据发送,那么TCP会重传数据(无论是客户端自己发送的数据还是保活探测),在重传一定次数后(一般是12次),客户端会给对端发送RST以关闭该连接,此时会将套接字的待处理错误设置为ETIMEDOUT,当此时再read/write时就会返回该错误。

  2. 服务器不可达时,如果有数据发送,那么TCP会重传数据(无论是客户端自己发送的数据还是保活探测),在重传一定次数后(一般是12次),客户端会给对端发送RST以关闭该连接,此时会将套接字的待处理错误设置为EHOSTUNREACH,当此时再read/write时就会返回该错误。

服务器崩溃重启
  1. 服务器崩溃重启,此时连接已经不复存在,此时如果客户端给服务器发送数据,那么会收到RST包,处理方法和第一种情况一样
epoll的EPOLLERR何时触发
  1. 对于epoll而言如果收到了RST包,那么epoll所触发的操作是 EPOLLIN+EPOLLRDHUP+EPOLLHUP+EPOLLERR
  2. 对端关闭连接收到FIN包会触发EPOLLRDHUP+EPOLLIN
  3. 本端shutdown读写时,如果不把该socket从epoll中移除,那么LT下会不断触发EPOLLIN+EPOLLHUP+EPOLLRDHUP
  4. 本端shtdown读,LT下会不断触发EPOLLIN+EPOLLRDHUP

注意,当close套接字时,该套接字会被内核自动从epoll中移除,但是shutdown的套接字则不会,如果不手动把shutdown的套接字移除,那么会不断触发EPOLLIN+EPOLLHUP+EPOLLRDHUP

https://blog.csdn.net/halfclear/article/details/78061771?utm_source=blogxgwz8

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!