《深入浅出TCP之6要认识到TCP是一个可靠的,但并不绝对可靠的协议》

6 要认识到TCP是一个可靠的,但并不绝对可靠的协议

6.1 可靠性是啥

  1. 第一个可以讨论确保可靠传输问题的地方就是应用程序B所在主机的tcp层。当一个段抵达应用程序B所在主机的tcp层时,唯一可以确认的就是这个段已经到达了,但它可能损坏了,可能是重复的数据,可能是错序的,或者是由于其他一些原因无法接受的。注意,发送端tcp无法对这些抵达接收端tcp的段作出任何保证。
    但接收端tcp要像发送端tcp确认,也就是说它ACK的数据以及在此数据之前到达的所有数据在tcp层都已经正确接收了,发送端tcp可以安全的删除这些数据的副本了。但是这并不意味着已经将数据传送,或者总是可以将数据传送给应用程序。比如,接收端主机可能在刚刚对数据进行了ACK,但应用程序还没有将其读取之前,就崩溃了。

  2. 另一个可以讨论确保可靠传输问题的地方就是应用程序B。我们知道,无法保证应用程序A发送的所有数据都会到达。tcp能够向应用程序B保证的是所有到达的数据都是按序且未受损的(未受损只是没有因特网校验和能够检测的错误,不能保证每个比特位都对的)

6.2 故障模式

  1. 网络中断
  • 路由器或骨干链路损毁,在端点(主机)之外发生的损毁通常是临时性的,因为路由协议会发现问题,并使路由绕开出问题的节点。端点出问题时,通常没有备份的路径,所以问题会一直存在,直到端点修复为止。
  • 中间路由器可能会向源端主机发送一条ICMP报文,说明目的网络或主机不可达,这种情况,有些实现会返回ENETUNREACH或EHOSTUNREACH。否则应用程序及其tcp/ip栈都无法立即获取中断的发生,这种情况下,发送端会最终超时,并重新发送多有未被确认的段。在发送端tcp放弃发送,丢弃连接并报告错误之前会一直持续这种操作,在传统的BSD栈中,发送端tcp会重传12次(大约9分钟)之后丢弃。如果读操作被挂起,会返回一条错误状况,并将error置为ETIMEDOUT。如果没有挂起的读操作,接下来的写操作就会失败,根据信号是忽略还是捕获,写操作失败时会携带一个SIGPIPE信号,或EPIPE错误。
  1. 对等实体崩溃

FIN是由TCP确认,而后让应用层read返回0
服务端回复RST,客户端再调read时,内核返回ECONNRESER

  • 这种情况下,对等实体的tcp都会向我们的tcp发送FIN。FIN作为EOF使用,表示发送它的那一端已经没有数据发送了。

  • 对等方崩溃和对等方调用close和exit是可不区分,在这两种情况下,对等方的TCP都是发送一个FIN消息给我们的TCP,FIN消息可以充当EOF,指示发送方没有任何数据可以发送了。如果此时有读操作挂起会立刻返回0,如果有写操作挂起那么会导致写操作成功,但是会导致对等方发送一个RST报文重置连接,那么当再次有写操作的时候, 应用程序会收到SIGPIPE信号,或者如果信号被捕获或忽略了,就会收到EPIPE错误。

服务器崩溃的时间线:
在这里插入图片描述

  • 向服务端发送一条报文,在服务端处理过程中,杀死服务进程,这种情况,客户端会立即接收到错误消息,说明服务器已经终止了。(收到FIN时,客户端阻塞在对read的调用,而tcp只要让read返回0就可以立即通知客户端)

客户端读操作挂起时服务器崩溃:

在这里插入图片描述

  1. 对等实体的主机崩溃
  • 这种情况,对等实体的tcp无法通过FIN通知我们的应用程序了,在对等实体重启之前,我们的应用程序tcp会持续传输未经确认的段,最终,如果对等实体主机没有重启,他就会放弃并向应用程序返回一条ETIMEDOUT错误。

  • 如果在我们的tcp放弃并丢弃连接之前,对等实体主机重启了,这种情况,tcp技术规范要求接收端主机向发送端主机回送一个RST,这样发送端主机就会丢弃连接,应用程序会收到一条ECONNERESET错误(挂起读操作)。或者会在下一条写操作时,应用程序会收到SIGPIPE信号,或者如果信号被捕获或忽略了,就会收到EPIPE错误。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值