前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据传输的主心骨,传输控制协议TCP:TCP基本概念和滑动窗口机制介绍

数据传输的主心骨,传输控制协议TCP:TCP基本概念和滑动窗口机制介绍

作者头像
望月从良
发布2019-07-01 16:49:11
6770
发布2019-07-01 16:49:11
举报
文章被收录于专栏:Coding迪斯尼Coding迪斯尼

我们在前面章节中描述了很多网络协议,它们共同的一个特点是居于UDP进行数据发送。在代码实现过程中我们发现,UDP包头非常简单,重要的就是有个端口,同时UDP协议的责任也简单,目的是标明数据包的归属,至于数据包能否正确发生给对方,它毫不关心。

UDP有个兄弟叫TCP,它的责任心就比UDP大很多。它不但关心数据包归属,而且全权负责数据包的准确发送,因此它的内容比UDP包头要复杂很多。从本节开始,我们要研究基于TCP之上的网络协议。由于我的特点是讲究实战与实践,与那些啰啰嗦嗦,华而不实,拉扯一大堆莫名其妙理论的学院派势不两立,因此我们将简要的了解TCP的大概内容,知道TCP数据包头的基本组织格式,然后立马投身基于TCP的上层协议的研究和开发上,更多TCP协议的内容将分散在具体实践中进行掌握。

在我看来TCP在现代的网络世界有点”不合时宜“。它庞大而复杂,了解他需要掌握很多细节和概念。之所以它那么复杂本质原因在于,它诞生在一个数据传输媒介的质量比较差,很容易出错的情况,它的复杂性就源自于要保证数据在传输不稳定,非常容易出错的情况下还要尽可能的保证数据包能正确投递。然而在现在的通讯时代,在5G已经比较成熟的情况下,数据传输的硬件在质量上愈发完善和稳定,数据传输过程中出错的可能性几乎为零,这使得TCP中很多用于控制数据传输的特性显得毫无必要,但TCP的设计思想非常精彩,同时如今依然有大量非常重要的网络协议运行在TCP之上,因此掌握TCP的设计思维以及要掌握很多基于TCP的高层协议时,了解TCP的内容依然无可避免。

获得理性认识的前提是要有感性认识。我们先看看TCP包头的样子,启动wireshark,设置过滤条件http,然后用浏览器打开一个网址,通过抓包后我们看看TCP数据包头的格式:

大家看上面截图,TCP包头与UDP包头相比,是不是字段更多,内容更繁杂。TCP说到底是为了帮助上层协议干脏活累活,它负责把数据准确发送给对方,这样上层协议就不用担心数据的准确性和稳定性问题,于是上层协议的设计就可以专注于解决具体领域问题。

TCP在传输上层协议的数据时会将要发送的数据看做管道中流出来的自来水。TCP就是一个盆,它打开水龙头接水,接满后给当前水盆打上一个标号,将这盆水发送给目的地。由于发送的一段数据有标号,这样就可以保证对方接收数据时确保数据顺序,同时通过应答的方式确保给定标号的数据包是否正常抵达目的地。

为了保证数据传输稳定性以及控制数据流保证信道通畅,TCP使用一种叫做滑动窗口的方法,这个是TCP协议里面最复杂最难以理解的概念。我们一点一滴慢慢道来。在网络数据传输中,一个难点是发送方不知道对方是否正确接收到数据,于是双方约定,对方收到后给发送方回送一个确认消息。然后复杂的网络情况会有多种异常情况,一种是对方没有收到数据所以没有回发确认消息;二是对方收到数据,回发确认消息,但是确认消息在传输过程中丢失。为了应对这种情况,发送方启动一个时钟,一旦在时间段内没有收到对方回复的确认数据包就再次重发,如下图:

这种方法存在一些缺陷,第一是效率低,如果A没有接收到B的回复时,它会一直等待而什么都不做,这是一种浪费;改进方法是A给发送的数据附加一个编号,B在回复时也附带对应编号。于是A就可以一下子发送多个数据包,然后根据回复中的编号检查哪些包被B接收,哪些没有。虽然这样对A方便了,但是对B则会带来问题,因为B现在一下子要处理很多数据包,它可能忙不过来。此时B需要告诉A它现在忙不过来,于是在回复包里再添加一个字段叫limit,告诉A一下子可以给B发送数据包的最大上限,于是A可以根据limit限制数据包的发送速率,其过程如下图:

在数据传输过程中,如果传输的数据量能够根据实际情况变化,那么效率就会提高。例如A想发送大块数据给B,但是B一下子承受不了,于是它让A在开始发送时将数据发送的量适当缩小,等到后面B有了空余的带宽,它就通知A将数据发送的量进行提升。在这种情况下,数据可以分成四种类型:1,数据已经发送而且已经被对方确认;2,数据已经发送但是还没有得到对方确认;3,数据没有发送但接收方可以接受;4,数据没有发送而且也接收方也没有能力接收,如下图:

上图中一个小方块代表一个字节。于是字节28-31属于类型1;字节32-45属于第二类型;字节46-51属于第三类型;字节52-57以后属于第四种类型。在这种情况下就可以引入“滑动窗口”的概念。此时为了提高效率,发送方可以将第二种情况的数据和第三种情况的数据合在一起发送,这种合并就叫“发送窗口”,具体情况如下图:

注意到一旦上面窗口内的数据发送出去后,第三类型的数据就转变成了类型二。此时类型二的数据是字节32-51.过一段时间后设备B发过来数据接收认证,它告诉A它所接收的数据范围.假设一开始A发送了4段数据后都没得到回复,这4段数据的范围分别为32-34,25-36,37-41,42-45,如果第1,2,4段数据抵达B,但第三段在传输过程中丢失,那么B就会发回一个认证包里面声明它接收到的数据范围,也就是32-36,虽然它接收到42-45,但是不会发送认证包,因为它会让A以为B收到了数据段37-41.

TCP使用这种认证方式叫累积认证系统,它会用它收到的最后一个字节数来标志前面所有数据的接收。现在假设当前发生窗口依然保持在20字节,由于此时A只能确认B收到了32-36这五个字节,也就是上图中窗口范围内的前五字节被确认接收,后面15字节没有被确认,于是A把这个窗口挪动5个字节,将挪动前窗口内的15个字节和挪动后新增加的5个字节一起发生过去,因此第二次发生的内容如下所示:

这种”滑动窗口“方式虽然在数据发送效率上很高,但是会带来新的复杂性,因为它会导致数据重复发送,例如前面37-41这段数据其实B已经收到,只是它的回复包在回传过程中丢失,那么第二次A再发送时,又把这段数据发送一次,而且这段数据还跟新数据混合在一起,这时就需要B做好处理。这里我们仅仅是在表面上大概介绍滑动窗口的机制,有很多复杂细节在后面实践时我们再深入展开。

TCP与UDP不同,它是一种”有连接“的传输,每启动一个TCP连接,双方就会建立起一个socket,socket是四种信息的组合,分别是发送者IP,发送者端口,接收者IP,接收者端口。socket可以保证多个TCP连接和传输能够并行进行而且互不干扰。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Coding迪斯尼 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档