TCP协议回顾

最近的经历发现TCP协议是个很好玩的东西,之前学的时候没什么感受,现在重新好好温习一次。
*注:传输层一般都是以sender(发送方)和receiver(接收方)来讨论,而不是客户端和服务器,因为任何联网的机器都可以作为sender或receiver。

A. 三次握手

三次握手的过程如下图所示,注意各个字段的值及其变化,如SYN(synchronize的缩写,同步),还有seq字段(sender和server都有各自的seq,至于为什么呢?在最后一部分中会说到)。
三次握手

不过重点是——为什么要三次握手,而不是一次、两次、四次握手?
其实我也不知道,google了一下,发现有很好的答案,现在分享下:
参考:【博客1】【博客2】
1)首先考虑一个场景,sender发送了一个请求打开TCP链接的包(A),中间延迟了一下,sender这边经过了timeout-interval,所以sender重新发了一个请求包(B),后来A也到达了receiver那边,那么receiver会作出什么反应呢?

  • 直接为每个请求包都打开一个TCP链接吗?
  • 很明显这样会浪费资源,因为包A是无效的了,sender那边已经认为它是丢失的包了,也不会通过它请求到的链接来传输数据。
  • 那该怎么办呢?receiver无法确定这个包是否有效。
  • receiver再发一个包回去询问呗,如果sender那边有相应的回应,那么就表示该包是一个有效的包。
  • 好,sender那边收到receiver发来的(对于A的)确认包,比较一下seq的值,发现不一样(因为这个值是sender随机出来的,所以前后两次相同的概率很小很小很小,一般可以认为是不一样的),好,那就不管它。
  • receiver那边呢?时间过了这么久了,还没收到sender的回应,所以它也可以认为刚才那个包(A)是无效的,好,风波告一段落!

综上所述,至少需要3次握手就可以避免这种情况的发生。至于为什么不能是4次,5次,6次,应该是(我觉得,这样能够基本保证就OK了,再多几次,延迟就太大了,得不偿失,trade-off的平衡过程?)。

2)摘录博客1的:这个问题的本质是,信道不可靠,但是通信双方需要就某个问题达成一致。而要解决这个问题,无论你在消息中包含什么信息,三次通信是理论上的最小值。所以三次握手不是TCP本身的要求,而是为了满足“在不可靠信道上可靠地传输信息”这一需求所导致的。

这个是从信息论的角度来回答的,大概知道是信息熵的意思,但我还不清楚其中的计算细节如何,等我这学期学完信息论再来补(小板凳在此)!!!

B. 四次挥手

过程如下图所示,同样注意FIN字段(Finish的缩写),还有其中等了一段时间(timed wait),这又是为什么呢?
四次挥手
由于TCP是全双工的(即双方可以互发数据),无论是客户端还是服务器端,都可以主动关闭正在通信中的链接,所以以下称主动关闭TCP链接的一方为“主动方”,另一方为“被动方”。
为什么不在“第二次挥手”时,被动方同时将ACK和FIN发送给主动方呢?要分两次这么麻烦?
注意刚刚说过,TCP的双方是可以互发数据的,你这边没数据发了(或者其它原因),想中断链接,但是那边可能还会有数据要发过来,TCP作为一个绅士优雅的协议,当然不能粗暴地不商量好就单方面断开啦,所以先等被动方发送ACK过来(如果timeout了,就继续发FIN,直到对方有回应),然后再等对方也发送完了,决定关闭链接了(第三次挥手,被动方发送FIN包),主动方这边再发一个ACK包确认已经收到被动方的FIN包。
咦,为什么主动方发送完ACK包之后还有一段Timed wait的时间!!!!(一般为2MSL,MSL表示段在网络中的最长生存时间,RFC中推荐规定为2分钟)原因可能很多,一个常说到的原因是——注意每次发包都是有time-out机制的,在最后这段Timed wait时间内,主动方会不断发包(超时才会重发)给被动方,如果被动方正确关闭了,那么将不会有任何回应;但是如果被动方没有正确关闭,就会发送回复的包。综上所述,这段时间是用来检查被动方有没有正确关闭的(悄悄问一句,如果发现没有正确关闭,那么主动方这边会怎么做呢?哈哈,可能得去看RFC文档才会知道了,教科书只会介绍最主要的原理,太细的细节得看专业的文档)

C. 发送方的窗口

“窗口”是TCP中一个很重要的概念,包括(发送方的)发送窗口,(接收方的)接收窗口,(发送方的)拥塞窗口,它们各有各的作用,现在先介绍发送窗口
首先注意到,目前为止谈论到的发送包,都是一个包发过去,等待对方发一个包回来,然后这边再发一个过去……毫无疑问这样的效率是很低的,如下图所示。
stop-and-wait
那么怎么提高发送的速度呢?注意到这有点像流水线(Pipeline,如果没学过计算机组成原理,也无所谓,理解成工厂里生产物品的过程就好了),发送方、传输媒介(整个网络)、接收方,三方的工作是独立开来的,前者的输出作为后者的输入,不明觉厉的可以看下下面这段比喻:

想象工厂制作一瓶饮料的时候,A车间先生产一个瓶子出来,送到B车间,B往里面装饮料,完了送到C车间加盖包装。那么在B装饮料的同时,A那边可以再生产一个瓶子出来,在B将瓶子送到C的时候,A马上就有一个瓶子送到B,是不是很快?当然这是假设三个工作的时间相同啦

用了流水线就有了下面的图了:
pipeline

其实有了流水线,就会出现较多的问题了,比如:发送方那边怎么接收?如果中间某个包丢掉了,而接收到了后面的包,这些“先到”的包是要丢弃掉吗?有不同的处理机制——Go-Back-N就是直接丢掉,所以它在接收方那边不需要缓冲区;Selective Repeat则是用一个缓冲区来缓存收到的包,即使是“先到”的包也会被接收。两者的效率可以比较直观就看出来~

说到这里,“发送窗口”到底是怎么回事呢?把要发送的数据看成一个包的数组,“发送窗口”就是一个在这个数组上的有限的连续的范围,比如[10, 10+6],其中10叫做窗口的base,6叫做窗口的大小。有什么用呢?它控制着流水线发送的包的数量,如果太少了,效率不高;如果太多了,一方面可能接收方那边受不了,丢包多,浪费流量,另一方面很容易造成网络拥塞。

至于这个窗口的大小是如何调节的,书里几乎没有谈及到,有兴趣的可以看一下相关的RFC文档(其实结合即将谈到的接收窗口和拥塞窗口,自己yy一个算法也是可以的)。

D. 接收窗口

C中也说到了,实行pipeline发送后,接收方如果使用相对比较高效的Selective Repeat策略的话,就需要一个缓冲区了,那么这个缓冲区也是有限的,如果太多包到达,它也接收不了,只能丢掉,但是这个信息得反馈回去给发送方啊,叫它慢点发,别浪费流量(2333,是不是跟日常人们的对话很像?)

那么怎么将“自己还能接收多少数据”的信息反馈回去呢?注意TCP段的数据结构,如下图所示,注意到首部是有一个叫做“Receive window”的字段,16 bit,它就是用来做这件事的,把自己的缓冲区还能装下多少数据放在这个字段,以发过去通知发送方。
TCP Segment

具体这个字段的值,就叫做接收窗口(Receive window),它的计算方式为:

RcvWindow = RcvBufferSize - [LastByteRcvd - LastByteRead]

这些量顾名思义就行了,也很容易理解,不赘述了。
PS,这种通过RecvWindow来控制发送方的方式叫做Flow Control,流控制。

E. 拥塞窗口

这是用来调整发送速率以达到尽量避开网络拥塞的,那么是根据什么信息来调整呢?

首先,想一下,sender这边能够收到什么信息?ACK嘛,没有ACK就有time-out的消息。进一步来看,time-out表示很有可能是网络太堵塞,然后丢包了。而ACK的表现呢?注意现在是实行了Pipeline的发送方式,它的ACK会是怎么样的呢?
fast-retransmit
如上图所示,如果是收到了同一个seq的三个ACK,也就是——中间某个包丢了,但后续的包到达了。这说明网络其实不是很拥堵的,很可能只是某个路由器偶尔的抽风而已(不然后续的包也到达不了对面)。所以,需要快速重传(等到time-out就太慢啦,提高速度!)

总结一下:
1. 如果收到Tri-ACK,就快速重传;
2. 如果没有收到三个ACK,并且time-out了,表示网络很堵塞,需要做出一些措施来避开这个堵塞(因为如果继续发送,会导致网络负担更重,甚至于崩溃)。

F. TCP的窗口的总结

其实CDE三部分介绍的三种窗口,分别对应的是发送方、接收方、传输媒介,这样来看的话,TCP的机制就很完整了,真心是个很巧妙的东西,不过看一下它的发展历史,也就不足为奇了,它是人们一边实践,一边修改才建立起来的机制,能不精巧吗?

G. TCP的拥塞控制机制

哈哈,激动人心的时刻到了,其实这部分不需要怎么说,直接看下面这个有限状态机就好了:
拥塞控制机制
注意三个状态,以及它们之间是怎么转化的。

首先是slow start,为什么要从很小的值(一般是1或2)开始呢?
这是因为TCP需要适应所有状况的网络,无论带宽有多大,所以它需要从小的值开始试探,而为了加快探测的时间,这个阶段的增长方式是“指数增长”!

然后是Congestion avoidance,这个就是探查到了接近当前这段网络能够承受的流量(根据预先设定好的阈值来判断),所以这个时候就不能继续翻倍地增加发送量了,线性增长就好了。

接着是Fast recovery,之所以会进入它,都是因为收到了三个ACK,表示需要快速重传。

最后需要说明的是time-out的时候会怎么办,无论在哪个状态发生time-out,都会直接进入slow-start!!!而这其中的阈值的变化、拥塞窗口的变化,具体数据看图就好了,下面是一个实例:
example

X. 更多

1)MSL(Maximum segment lifetime)、TTL(Time to live)以及RTT(Round trip time)的关系:http://wushank.blog.51cto.com/3489095/1135060
2)如果两边几乎同时发出FIN包,在收到对方的ACK之前,先收到了FIN,这是个有趣的情况,不过目前还不知道会发生什么事。
3)Wiki关于MSL的描述:https://en.wikipedia.org/wiki/Maximum_segment_lifetime
4)致谢:本文的图片均截图自《Computer Networking A Top-Down Approach》第六版,谢谢,如有侵权,请通过博客联系我删除。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值