tcpsocket无法收到重传报文
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了tcpsocket无法收到重传报文相关的知识,希望对你有一定的参考价值。
- 在网络层面,传输都可能存在丢包和不可靠。tcp之所以可靠,是因为他有重传机制。但即使如此,也不能说百分之百就一定能送达,也就是当重传还是丢了后,tcp也表示无能为力,几番尝试无果就只能断链接了。当然这时你可以选择重链接,但谁也不能保证重连就一定能连上。所以,一切还是看具体怎么实现,怎么考虑各种极端的网络情况。网络特别特别好,udp传输也不怎么丢包的。- 同意,TCP可靠是基于双方都知道彼此的字节流的原点,发送方对于自己发送的字节流一定要接收到对方的确认,才会从发送缓冲区彻底删除,如果没有得到确认,会一直重传,如果重传次数到达极限值,则reset TCP 连接。而UDP则不同,把数据发出去就不管了,也没有缓存区来缓存发出去而没有确认的数据,因为压根不会发生,此外也无需内存来保存类似TCP各种状态位。
简单回答的话,在TCP的实现方面,超时重传 快速重传和SACK机制都能在这种情况下实现让客户端重新传输丢掉的第2个包,分别讲讲三种不同的机制
1. 超时重传
客户端通过tcp一次性把数据都发送了出去,在未收到这些发出报文的ack确认之间,这些报文仍然会缓存在发送队列里,如果在限定的时间内(RTO 重传过期时间)没有收到对应报文的ack,那么这些报文需要被重传
RTO不是静态配置的,在这个问题里系统会根据前面三次握手和第一个报文的ack的RTT计算出来一个RTO,这个时间可能是200ms到120s之间的一个值,所有到了RTO时间没有收到ack的报文都需要被重新传送到网络上
2. 快速重传
等待一个RTO的时间太久了,尤其是在RTT比较大的网络环境里,如果丢包率再比较高的情况,那么TCP的效率就会非常低,所以需要通过快速重传机制来实现优化
简单来说,客户端发送的第2个报文丢了,没有收到ack,但服务器在收到第3 4 5个包时会检查他们的顺序编号sequence number,并察觉到与第1个包之间并不连续,于是会发送3个连续的dup ack 给客户端,要求客户端重新发送第1个包后面具有正确sequence number的报文 客户端在收到三个连续的dup ack之后就会确认第2个报文丢掉了,于是实现立即重传而不用再等到RTO的过期时间
3. SACK selective acknowledgment
如果只是丢了第2个包其实快速重传机制就已经可以搞定了,但如果在中间丢了多个报文的时候,比如2-9之间可能丢了第3,第5和第7个报文,其他报文都已经顺利到达服务器,如果只有快速重传,那么客户端需要重传从3到第7个之间的所有报文,而如果客户端和服务器都支持sack的话,服务器端就可以通过sack选项来告知发送方到底丢了哪些报文,这样客户端就只需要把对应丢失的报文重传就好了。二、TCP重传
1、重传的原因
1)发端计时器超时
TCP每发送一个报文段,就对这个报文段设置一次计时器。当计时器超时而没有收到确认时,就重传该报文。
注:原来报文哪去了呢?两种可能:1)在中间节点丢了。2)还在路上,走的慢。
对于第一种情况:接收端是不知情的,而对于第二种情况,接收端表现为收到两个一摸一样的报文。 参考技术A 如果tcpsocket无法收到重传报文,建议如下操作:
1. 找运维同事确定是否是网线问题, 如果是网线问题请更换网线。
2. 使用ping 确定是不是网络问题, 通常系统自带的ping命令是走ICMP协议,这个是基于IP层的协议,和tcp协议是同一级别的,所以我们还需要使用。
tcp协议的ping, tcp协议的ping我可以使用下面的脚本进行测试。 参考技术B - 在网络层面,传输都可能存在丢包和不可靠。tcp之所以可靠,是因为他有重传机制。但即使如此,也不能说百分之百就一定能送达,也就是当重传还是丢了后,tcp也表示无能为力,几番尝试无果就只能断链接了。当然这时你可以选择重链接,但谁也不能保证重连就一定能连上。所以,一切还是看具体怎么实现,怎么考虑各种极端的网络情况。网络特别特别好,udp传输也不怎么丢包的。
- 同意,TCP可靠是基于双方都知道彼此的字节流的原点,发送方对于自己发送的字节流一定要接收到对方的确认,才会从发送缓冲区彻底删除,如果没有得到确认,会一直重传,如果重传次数到达极限值,则reset TCP 连接。而UDP则不同,把数据发出去就不管了,也没有缓存区来缓存发出去而没有确认的数据,因为压根不会发生,此外也无需内存来保存类似TCP各种状态位。
简单回答的话,在TCP的实现方面,超时重传 快速重传和SACK机制都能在这种情况下实现让客户端重新传输丢掉的第2个包,分别讲讲三种不同的机制
1. 超时重传
客户端通过tcp一次性把数据都发送了出去,在未收到这些发出报文的ack确认之间,这些报文仍然会缓存在发送队列里,如果在限定的时间内(RTO 重传过期时间)没有收到对应报文的ack,那么这些报文需要被重传
RTO不是静态配置的,在这个问题里系统会根据前面三次握手和第一个报文的ack的RTT计算出来一个RTO,这个时间可能是200ms到120s之间的一个值,所有到了RTO时间没有收到ack的报文都需要被重新传送到网络上
2. 快速重传
等待一个RTO的时间太久了,尤其是在RTT比较大的网络环境里,如果丢包率再比较高的情况,那么TCP的效率就会非常低,所以需要通过快速重传机制来实现优化
简单来说,客户端发送的第2个报文丢了,没有收到ack,但服务器在收到第3 4 5个包时会检查他们的顺序编号sequence number,并察觉到与第1个包之间并不连续,于是会发送3个连续的dup ack 给客户端,要求客户端重新发送第1个包后面具有正确sequence number的报文 客户端在收到三个连续的dup ack之后就会确认第2个报文丢掉了,于是实现立即重传而不用再等到RTO的过期时间
3. SACK selective acknowledgment
如果只是丢了第2个包其实快速重传机制就已经可以搞定了,但如果在中间丢了多个报文的时候,比如2-9之间可能丢了第3,第5和第7个报文,其他报文都已经顺利到达服务器,如果只有快速重传,那么客户端需要重传从3到第7个之间的所有报文,而如果客户端和服务器都支持sack的话,服务器端就可以通过sack选项来告知发送方到底丢了哪些报文,这样客户端就只需要把对应丢失的报文重传就好了。 参考技术C - 在网络层面,传输都可能存在丢包和不可靠。tcp之所以可靠,是因为他有重传机制。但即使如此,也不能说百分之百就一定能送达,也就是当重传还是丢了后,tcp也表示无能为力,几番尝试无果就只能断链接了。当然这时你可以选择重链接,但谁也不能保证重连就一定能连上。所以,一切还是看具体怎么实现,怎么考虑各种极端的网络情况。网络特别特别好,udp传输也不怎么丢包的。
- 同意,TCP可靠是基于双方都知道彼此的字节流的原点,发送方对于自己发送的字节流一定要接收到对方的确认,才会从发送缓冲区彻底删除,如果没有得到确认,会一直重传,如果重传次数到达极限值,则reset TCP 连接。而UDP则不同,把数据发出去就不管了,也没有缓存区来缓存发出去而没有确认的数据,因为压根不会发生,此外也无需内存来保存类似TCP各种状态位。
简单回答的话,在TCP的实现方面,超时重传 快速重传和SACK机制都能在这种情况下实现让客户端重新传输丢掉的第2个包,分别讲讲三种不同的机制
1. 超时重传
客户端通过tcp一次性把数据都发送了出去,在未收到这些发出报文的ack确认之间,这些报文仍然会缓存在发送队列里,如果在限定的时间内(RTO 重传过期时间)没有收到对应报文的ack,那么这些报文需要被重传
RTO不是静态配置的,在这个问题里系统会根据前面三次握手和第一个报文的ack的RTT计算出来一个RTO,这个时间可能是200ms到120s之间的一个值,所有到了RTO时间没有收到ack的报文都需要被重新传送到网络上
2. 快速重传
等待一个RTO的时间太久了,尤其是在RTT比较大的网络环境里,如果丢包率再比较高的情况,那么TCP的效率就会非常低,所以需要通过快速重传机制来实现优化
简单来说,客户端发送的第2个报文丢了,没有收到ack,但服务器在收到第3 4 5个包时会检查他们的顺序编号sequence number,并察觉到与第1个包之间并不连续,于是会发送3个连续的dup ack 给客户端,要求客户端重新发送第1个包后面具有正确sequence number的报文 客户端在收到三个连续的dup ack之后就会确认第2个报文丢掉了,于是实现立即重传而不用再等到RTO的过期时间
3. SACK selective acknowledgment
如果只是丢了第2个包其实快速重传机制就已经可以搞定了,但如果在中间丢了多个报文的时候,比如2-9之间可能丢了第3,第5和第7个报文,其他报文都已经顺利到达服务器,如果只有快速重传,那么客户端需要重传从3到第7个之间的所有报文,而如果客户端和服务器都支持sack的话,服务器端就可以通过sack选项来告知发送方到底丢了哪些报文,这样客户端就只需要把对应丢失的报文重传就好了。 参考技术D 处理线上问题经常会碰到网络抖动的情况, 网络抖动有可能就是TCP重传导致,下面简单说下TCP重传的排查思路,不一定能完全解决问题
1. 找运维同事确定是否是网线问题, 如果是网线问题请更换网线
2. 使用ping 确定是不是网络问题, 通常系统自带的ping命令是走ICMP协议,这个是基于IP层的协议,和tcp协议是同一级别的,所以我们还需要使用
tcp协议的ping, tcp协议的ping我可以使用下面的脚本进行测试。
TCP的四种定时器
一、重传计时器
TCP提供可靠机制,因此对于丢失的报文需要进行重传!
那么,发送一个数据出去之后,什么时候进行重传呢?用到了重传定时器.
在发送数据后,便立刻创建一个该报文段的重传定时器.
如果定时器还没结束,收到了确认报文,则撤销该定时器.
如果定时器结束,还没收到确认报文,则进行重发.
定时器时间为动态计算的,常见公式新RTT=旧RTT的90%+当前RTT*10%
二、坚持计时器
接受方窗口为0,则发送端会停止发送,直至收到接受方窗口不为0的通告.
但是,如果接受方窗口不为0的通告丢失了,则会产生死锁!!!!
接受方等发送方发送数据,发送方等接受方发送窗口不为0的通告(窗口不为1的通告报文丢失).......
因此,需要一个计时器来解决这个问题.
当接受方窗口为0,发送方激活该计时器,如果计时器结束,还没收到接受方窗口不为0的通告.
此时,发送方会向接受方发送探测报文.如果接受方窗口依然为0,则计时器的值加倍复位,直到计时器的值达到一个阙值.
如果接受方窗口不为0,则继续传输数据...
三、保活计时器
每次服务器收到客户端数据时,重置保活定时器,
如果保活定时器为0,则发送探测报文段,若发送10个报文段还是没有响应,则终止链接.
四、时间等待计时器
当断开连接后,主动断开的一方会进入TIME_WAIT状态,防止一些超时、游离报文、重复的FIN报文被丢弃。
以上是关于tcpsocket无法收到重传报文的主要内容,如果未能解决你的问题,请参考以下文章