携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情 >>
TCP连接时,随机产生初始化序列号的原因
相信学习过网络的各位朋友们对TCP已经相当熟悉了,应该也知道这么一回事:每次创建TCP连接的时候,TCP的初始序列号都是随机生成的,每次都不一样的。
可是为什么要这样呢?不随机不可以吗?每次相同不可以吗?
相信看到这里各位技术大佬们已经有了自己的答案了,不管怎样来到了这里,那咱们就一起再学习一下吧。
出发!
知识准备
TCP可靠传输的一部分原因是因为它采用了序列号对字节数据进行编号,接收方在收到数据的时候,会给出相应的确认;假如数据丢失或者确认丢失,则发送方会触发超时重传。
当然啦,序列号还有确保按序接收等等功能,这里就不一一介绍了。
随机产生初始序列号的原因
TCP的连接由四元组唯一确认。
四元组:<源IP,源端口;目的IP,目的端口>
随机产生初始序列号的原因主要是为了避免历史报文对当前四元组连接的影响(防止当前连接接收已经失效连接的历史报文)
为什么会出现这种问题呢?(假设初始序列号都相同)
我们都知道TCP在断开连接的时候会进行四次挥手,这已经把所有的瓜葛都分得清清楚楚了啊,第四次挥挥手的时候,客户端还等待了2MSL呢;这已经可以让双方都断开连接了啊。
其实上述谈论的都是基于一个理想的场景下谈论的,假如说服务器突然断电重启了呢?这样的场景还是很有可能发生的。
假如服务器断电重启之前,客户端发出的报文A由于网络阻塞还没达到;断电重启之后,收到客户端超时重传的TCP报文AA,因为服务端已经断电重启了,先前的TCP连接已经不存在了,所以此时服务端会返回reset(RST)给客户端。
客户端收到rst后,又重新与服务端建立新的连接(在假设每次建立连接时的初始序列号都相同的情况下,那么此时的初始序号和先前那次连接的是一样的),即两次连接的四元组相同。
而如果这时候历史报文A到达服务端,而序号又刚好在服务端的接收窗口范围内的话,就会被服务端接收,而服务端因为接收了历史报文将导致数据错乱。
为了随机产生初始化序列号就可以解决了呢?
随机产生的初始化序列号,可以让前后两个连接的接收窗口范围有千渊之别,比如第一个连接的初始序列号为 0 ,第二个连接的初始序号为100,000,这样你觉得第一个连接的历史报文序列号刚好在第二个连接的接收方的接收窗口范围内的可能性有多大??
小之又小!
这里需要说明一点,采用随机产生初始化序列号并不代表着完全解决了上述问题,它只是在很大程度上避免了接收历史报文。两个点:
- 随机产生也是有可能产生相同的
- 是否会接收历史报文,主要是看该历史报文的序列号是否落在了接收方的接收窗口的范围内