TCP知识小结(3)

169 阅读3分钟

最近连续看了一个微信公众号小林coding的图解网络的文章,收获挺多。在这里发文小结一下,也方便后续工作中查询。

如何在不kill进程的情况下关闭TCP连接

Linux有一个工具killcx, 可以关闭TCP连接。原理就是伪装客户端发送一个SYN报文,一般情况下这个报文的序列号不会是当前滑动窗口中的有效序列号,服务端会回一个ACK报文(称之为Challenge ACK),带上期待的序列号。收到了ACK报文后,再分别以ACK的序列号和期待的应答序列号发送RST报文给客户端和服务端。客户端和服务端收到了RST报文,都以为是对端发送的,就会关掉连接了。

这个就是黑客干的活,无故切断连接。

序列号为什么每次不一样

主要是为了避免接收到历史报文后,降低历史报文序列号在有效窗口内的概率。如果不再有效窗口内,报文会被丢弃,而不会对正常流程产生影响。

为什么要有TIME_WAIT状态

TIME_WAIT状态是主动断开连接方在发送完FIN_ACK后,延迟关闭连接。这个时间足以使两个方向的包在网络中自然消失,而不会留到下一个连接中。同时保证对端可以正常关闭,防止会给对端的FIN_ACK丢失,继续处理对端重传来的FIN报文。

什么情况下SYN报文被丢弃

在开启了tcp_tw_recycle参数,并且在NAT环境下,造成SYN报文被丢弃。主要是NAT环境下有个PAWS机制,根据IP作防止回绕的,经过NAT后的多个客户端被当成同一个了,无法区分了。

另一种情况就是accept队列慢了,新的syn报文就被丢了。

TCP如何保证按序可靠交付报文

TCP是一个可靠的传输协议,如何保证可靠呢?传输过程中的数据包破坏、丢包、重复以及分片乱序如何处理的?

TCP通过序列号、确认应答、重传机制、连接管理和窗口控制等机制来保证。

重传机制

主要有四种重传: 超时重传、快速重传、SACK、D-SACK

超时重传就是发送方在指定时间没有收到接收方应答的ACK。可能是发送包丢失或者ACK包丢失,阻塞了。这个是以时间来衡量是否需要重传的。

快速重传收到多个ACK的下一个报文序列号相同的,触发重传对应的报文或者是之后的报文,具体根据实现来决定。

SACK就是接收方在TCP首部会发送缓存的地图,发送方就可以知道要选择重传那些报文了。

D-SACK 使用SACK告诉发送方哪些数据已经被接收了。发送方就知道哪些包丢了,发送那些包就行了。

滑动窗口

就是约定一个窗口的大小,在这个范围内不需要等待ACK可以直接发送。提高发送的效率。窗口大小是接收方决定的,就看接收方可以缓存多大的数据包。

流量控制

当应用程序来不及取走数据时,可用窗口会渐渐的变成0. 窗口开放后,接收方会发送一个端口开放的ACK。 如果ACK丢了,发送方会超时探测窗口大小,获取到新的窗口后再决定发送数据。

糊涂窗口综合症

就是窗口太小了,然后发送方每次只放松很少的数据,占用带宽。可以使用Nagle算法来解决。 只有窗口>=MSS 或者数据 >=MSS, 并收到了之前的ACK才发送数据。

也可以不让接收方回小窗口的报文。当接收窗口 < MSS/2时,直接调整窗口大小为0。

拥塞控制

根据网络拥塞情况,发送方调整发送的数据量,防止过多的报文重传造成网络更加拥塞。 发送方没有再约定时间接收到ACK包,就认为网络拥塞了,然后减小拥塞窗口,相反的 就会加大拥塞窗口。

慢启动 拥塞避免 拥塞发生 快速恢复

后面的具体内容比较详细,不一一记录了。

更多

TCP是一个复杂的协议,在协议的算法及约定上面也采取了很多巧妙的设定。为了优化协议或者是解决问题,进行了多种考量。同时也提供了许多参数设定。精彩之处,需要多次学习,一点点吃透,有待挖掘更多的知识,先这样了。


行动,才不会被动!

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。