关于tcp协议可靠数据传输原理的记录

来源:互联网 发布:淘宝流量和访客 编辑:程序博客网 时间:2024/05/21 05:55

首先各位推荐b站上的一个计算机网络课程,讲的很好很全面:

计算机网络之探赜索隐

http://www.bilibili.com/video/av8377571/


网络层的数据传输是不可靠的,分组在传送的过程中可能会产生位错误,延时,丢失等等情况。而运输层tcp协议的作用之一就是通过制定一系列规则让通信双方具有可靠的传输信道。

从这个角度来看,关于这部分内容,我们学习的其实是一种思想,是一种可以应用在与计算机网络无关的场景下的一种工作模式。

课程中首先假设信道是完全可靠的,并给出对应的通信协议,然后将可能发生的错误不断加入,并不断修改通信协议解决这个问题。这样一个过渡过程会让我们比较好理解最终这个复杂的协议的工作原理。

rdt1.0:通信完全可靠。

rdt2.0:在rdt1.0基础上,认为传送的分组可能会产生位错误,不考虑分组的丢失和延时。解决办法是:1利用校验和检验位错误。2利用确认机制(ack),每次在接收方收到一个分组后,如果分组没有位错误,发送ack给发送方,否则发送nak给发送方。如果发送方收到nak,则重传分组。

rdt2.1:在rdt2.0基础上,认为ack和nak本身在传送的过程中也会产生位错误。解决办法是:1如果ack或者nak传送过程中产生位错误,则发送方进行重传分组,但是这样会带来一个新的问题,接收方可能会因此得到一个重复的分组,而他自己无法识别。为此我们又加入一种机制:序列号机制。即把分组用0,1序列号交替标记,这样的话如果发送方重传分组,接收方会发现他本来在等待1号分组,结果传过来一个0号分组,那么他就会知道,这是个重复分组,并将它丢弃。

rdt2.2:在rdt2.1基础上,我们考虑以下问题:我们是不是需要ack和nak两种消息同时存在?答案是我们可以只保留ack消息即可,其实这很好理解:ack和nak同时存在的意义在于可以标识两种不同的状态,如果我们将0和1序列号保存在ack中,发送方原来会收到ack和nak,现在则收到ack0和ack1,并且意义也发生了改变。ack0代表着接收方最后接收到的正确的分组是0号分组,ack1代表接收方最后接收到的正确的分组是1号分组。

rdt3.0:在rdt2.2基础上,我们考虑以下问题:在之前的问题中,我们默认分组总能及时到达接收方,不管它是不是正确的。但是实际情况中,一方面分组可能在传送过程中丢失,另一方面分组可能在信道中逗留很长时间。我们不可能因为一个分组的丢失或者延时而不停的等下去,这不合理。所以我们必须在发送方发送一个分组后,如果在某一个合理的时间内没有ack0或者ack1从接收方发送过来,就重发分组。这样做会导致什么问题呢?考虑如果ack0或者ack1没有丢失,而是在信道中逗留过久,在到达发送方前,发送方已经重发了分组,这样接收方会收到重复分组(事实上序列号机制解决了这个问题),而发送方在任何时候都可能收到一个ack0或者ack1。可以在下面的有限自动状态机中看到,这个问题被解决了。


rdt3.0 发送方有限自动状态机

rdt3.0  接收方有限状态自动机


(这个图是rdt2.2中接收方的自动机,但我觉得rdt3.0中和这个应该是一样的,如有错误欢迎指出。)


总结: 在rdt3.0中我们可以看到发送方的宗旨就是:只有我按时收到了对应的ack,我才进入发送下一个分组的状态,否则我就重传这个分组(比如ack不对应,ack位错误,ack超时)。而我在等待上层调用的过程中也可能会收到ack(接收方发送的延时到达),忽略他即可。

而接收方的宗旨是:如果我在等待0号分组时:收到了位错误的分组,则返回最后一个正确分组的序列号对应的ack(ack1);收到了1号分组(接收方知道这应该是接收方发送的上一个ack1在信道上丢失或者发生了位错误,导致发送方重发了这个分组,但接收方其实已经有了这个正确的分组),发送ack1回去,丢弃这个分组,让发送方进入下一个状态;收到了0号分组,上交上层应用,进入下一个状态。

原创粉丝点击