作者回复: 回答的很详细,很明显经过了仔细的思考,不是随便写的,不光为你的答案,我更要为你的学习态度点赞! udp这部分,协议要求是udp载荷不要超过512字节,比常见MTU小很多,所以可能这个超出MTU的问题没有tcp那样严重。但是就像你说的,udp丢包的话,相应的容错和重传,协议栈本身是不做的,这就给应用程序提出了要求。 从运维角度分析的答案也很好,我也是很看重这一点:如果把配置“藏”在各个地方而其他人不知道,就等于是给其他运维和开发人员“埋雷”,我们应该尽量避免。
作者回复: 多谢补充,工具的使用方面有很多小的细节:)
作者回复: 很好,自己想明白了这知识就真的是你的了:)
作者回复: 您好,图中tunnel1也是用在gz和bj服务器之间的,并不是仅仅在gz和bj lb之间。 第二个问题,mss改为1400是一个示例,并不是说当时这个案例就是用了这个数值。 有任何其他疑问也都可以提哈
作者回复: 中间设备负责转发,但因为IP和TCP报文是不加密的,所以可以在中间环节修改这些转发报文的MSS字段,这就起到了让通信两端都按照修改后的MSS进行传输的效果。 理论上说,不光MSS,几乎其他任何IP头部和TCP头部字段都可以被中间设备修改。
作者回复: Linux对MSS会随时间发生变化这一点也是有机制来保护的,比如依赖PMTU报文进行调整。PMTU是网络设备会遵循的协议,当设备收到一个超过其MTU的报文时,一方面会丢弃,一方面会返回一个Destination Unreachable的ICMP消息,具体可以参考RFC 1191: https://www.rfc-editor.org/rfc/rfc1191 由于网络的复杂性,这种ICMP消息经常会被拦截,导致发送端压根不知道自己的报文因为MTU超限而被丢弃了,就会导致各种问题。 在已经知道有隧道的情况下,尽量设置合理的相对低的MTU值,是保障网络通信的一个经验。
作者回复: 谢谢支持,也希望大家坚持学习和反馈,通过这门课程,提升对网络的理解,和网络排查的水平~
作者回复: 关于这3个问题: 1. 你看到DupAck to从#31变成了#3,是因为截图的问题,#3那个是另外单独保存的抓包文件,所以编号不一样,但是TCP流确实是同一个。这个截图我们刚替换成统一#31的,也感谢你的细心! 2. 这两次对#31报文的DupAck,只是因为握手之后的第一个数据报文(也就是1388字节那个)没有到客户端,但后面两个报文到了,所以客户端回复的两次ack号只能停留在握手结束的时候。这不是说客户端收到了两次SYN+ACK。DupAck的意思是:“我需要你那边跟这个ack号等值的seq号的报文”,而不是“我需要你再发一次我刚刚ack过的报文”,这里正好差了一个“身位”,你再想想? 3. ack是内核协议栈回复的,你可以从github上git clone一下linux内核代码,然后在IDE里,搜一下TCPHDR_ACK在代码中的位置。大体上说,ACK标志位的设置是一类函数,比如SYN、FIN、RST(不含被动RST)、传输阶段等报文都是在各自不同的函数里面设置了ACK标志位,而它们的发送都会走到tcp_transmit_skb()来完成。 kcp没了解,也没用过:(
作者回复: MTU当然是三层的,属于IP报文的长度,一般是1500字节。
作者回复: 是的,不过这里的麻烦是由于很多网络限制,通信两端其实经常无法收到PMTU ICMP消息,也就导致无法及时调整MSS来适配网络状况,也是文中案例的诱因之一。