理解TCP可靠的通信

时间:2021-10-31 17:31:59

1、TCP通信是可靠的,UDP通信是不可靠的。TCP是怎么保证通信可靠的呢?

2、实际项目中,用到串口通信,也要保证通信可靠,TCP的道理应该也是一样的。

3、通信之前,三次握手。可以这样认为:a、甲问乙一个问题;b、乙回答甲的问题,同时问甲一个问题;c、甲再回答乙的问题。这样证明二者连接正常了,可以进行数据传输了。

4、通信是可靠的,也就是说,甲如何确认乙收到了自己发的信息?

  甲乙通信的信息中有两个字段,SendNum和AckNum,SendNum表示向对方问第几个问题,AckNum表示收到了对方的问题,回答对方第几个问题。注意:这种回答方式很特殊,别人问什么,我就把问题重复一边作为回答。

5、甲乙双方都维护两个内容:当前问到第几个问题CurrNum和最后一次发给对方的信息LastMsg。发送信息的机制是:对方回答了自己刚才的问题,才问下一个问题。以甲为例说明,收到乙的信息,查看乙的AckNum是否与自己的CurrNum相等,如果相等,说明乙收到了刚才发的信息,++CurrNum,向乙发送下一个信息。如果AckNum与CurrNum不相等,注意AckNum只可能比CurrNum小1。说明乙没有收到刚才发的信息,而是收到了更前一次的消息。在这种情况下,甲把最后一次发的信息LastMsg最发一次。

6、现在思考,AckNum与CurrNum不相等的情况下,AckNum为什么只可能比CurrNum小1?

  消息发送的机制是:确认对方收到了刚才的信息,才发下一个信息。

  假设AckNum比CurrNum小2,或者更多。比如AckNum为3,CurrNum为5,这就相当于对方会没回答第4个问题,我就已经问了第5个问题,这显然与前提矛盾。

  假设AckNum比CurrNum大,这就相当于我还没问这个问题,对方已经回答了,这显然与前提矛盾。

7、对方回答了当前问题,我才问下一个,这种方式效率低。有没有更好的办法呢?

  甲把信息从1到10准备好,搞一个大小为5的集合,包含1到5这5个信息。甲不用等待乙回答了第一个问题,才问下一个问题,而是可以接着问5个问题,当问到第5个问题,乙还没有回答第1个问题,那就必须等待了。当乙回答了第1个问题,集合向前移动一个单位,表示甲可以发送第6个问题了,等待乙回答第2个问题。这就是滑动窗口协议的基本思想。

  考虑下面的情况,甲一口气问了5个问题,乙接收到了5个问题。但是,乙只正确回答了第1个,第2个问题,回答第3个问题的时候出错了。这个时候,甲认为第3个问题,乙没有正确接收,于是把3,4,5这三个问题,重新问一遍。乙收到甲,再次问第3个问题,也意识到从第3个开始,就出错了,于是把后面收到了第4,第5这两个问题也丢弃,重新接收。

8、TCP一连接好,就发送大量信息,往往会导致阻塞。发送方不知道接收方的处理能力,就采取试探性的策略。先发大小为1的消息试试,没问题,再发大小为2消息试试,还没问题,就发大小为4的消息试试,采用几何数级增长。这就是慢启动算法,慢启动并不慢,只是刚开始很慢,速度很快就上来了。