前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布

TCP

作者头像
IT技术小咖
发布2019-11-24 18:16:46
1.2K0
发布2019-11-24 18:16:46
举报
文章被收录于专栏:码上修行码上修行

学习 TCP 协议,首先第一个要了解当然是 TCP 连接是如何建立的,下面给大家介绍一下三次握手和四次挥手的过程以及为什么要这样设计。

三次握手

在基于 TCP 通信中,双方要进行通信,则需要建立一个物理连接,建立时需要双方进行三次握手,成功即可完成连接建立。

采用三次握手的原因:

  在网络通信中,网络存在拥塞,发送的报文可能会由于网络拥塞的原因,导致对方收不到。若采用直接开启连接,当客户端发送连接建立请求后,不等待确认服务器可以打开连接就直接打开连接,这样如果服务器收不到报文,根本不知道客户端,那么客户端的打开的物理连接是无效的,但客户端不知道,还一直发送数据,做无用的工作。

三次握手的过程

四次挥手

当双方通信结束时,需要四次挥手来关闭连接。

采用四次挥手的原因:

  学习过 TCP 连接的都知道,TCP 连接是双向的,一个是从客户端到服务端,另一个是从服务端到客户端。假设当前客户端已经发送完所有数据到服务器,则此时可以告知服务器,我已经发送完数据了,可以关闭我这端到另一端的通道,服务器收到关闭报文则可发送一个确认,确认关闭;但此时由于服务器可能还需要发送数据到客户端,因此并不会关闭从服务端到客户端方向的通道;等服务端发完了,才发送一个 FIN 报文给客户端,客户端收到之后发送确认,则此时 TCP 连接才正式关闭。

四次挥手的过程

TIME_WAIT状态

从四次挥手过程可以看到,当服务器像客户端发送 FIN 报文后,客户端响应确认报文时,客户端处于 TIME_WAIT 状态,而不是处于 CLOSE 状态。之所以会这样主要是因为客户端发送确认报文后,不能立刻关闭连接。因为如果服务端收不到确认报文,会将 FIN 报文重传,但此时客户端已经关闭连接了,这样会导致客户端收不到,而服务端则一直苦苦等待客户端发送确认报文,不断重传 FIN 报文。因此客户端在响应确认报文后,需要等待两个报文往返时间,以此来确保服务端能够正常收到确认报文关闭连接。

TCP的优势

从传输数据来讲,TCP/UDP以及其他协议都可以完成数据的传输,从一端传输到另外一端,TCP比较出众的一点就是提供一个可靠的,流控的数据传输,所以实现起来要比其他协议复杂的多,先来看下这两个修饰词的意义:

1. Reliability ,提供TCP的可靠性,TCP的传输要保证数据能够准确到达目的地,如果不能,需要能检测出来并且重新发送数据。

2. Data Flow Control,提供TCP的流控特性,管理发送数据的速率,不要超过设备的承载能力

为了能够实现以上2点,TCP实现了很多细节的功能来保证数据传输,比如说 滑动窗口适应系统,超时重传机制,累计ACK等,这次先介绍一下滑动窗口的一些知识点。

滑动窗口引入

在阅读一些文章的时候看到一个大牛做的视频,非常不错易于理解滑动窗口的机制,可以先看下:http://v.youku.com/v_show/id_XNDg1NDUyMDUy.html

IP层协议属于不可靠的协议,IP层并不关系数据是否发送到了对端,TCP通过确认机制来保证数据传输的可靠性,在比较早的时候使用的是send--wait--send的模式,其实这种模式叫做stop-wait模式,发送数据方在发送数据之后会启动定时器,但是如果数据或者ACK丢失,那么定时器到期之后,收不到ACK就认为发送出现状况,要进行重传。这样就会降低了通信的效率,如下图所示,这种方式被称为 positive acknowledgment with retransmission (PAR)

滑动窗口

可以假设一下,来优化一下PAR效率低的缺点,比如我让发送的每一个包都有一个id,接收端必须对每一个包进行确认,这样设备A一次多发送几个片段,而不必等候ACK,同时接收端也要告知它能够收多少,这样发送端发起来也有个限制,当然还需要保证顺序性,不要乱序,对于乱序的状况,我们可以允许等待一定情况下的乱序,比如说先缓存提前到的数据,然后去等待需要的数据,如果一定时间没来就DROP掉,来保证顺序性!

在TCP/IP协议栈中,滑动窗口的引入可以解决此问题,先来看从概念上数据分为哪些类

1. Sent and Acknowledged:这些数据表示已经发送成功并已经被确认的数据,比如图中的前31个bytes,这些数据其实的位置是在窗口之外了,因为窗口内顺序最低的被确认之后,要移除窗口,实际上是窗口进行合拢,同时打开接收新的带发送的数据

2. Send But Not Yet Acknowledged:这部分数据称为发送但没有被确认,数据被发送出去,没有收到接收端的ACK,认为并没有完成发送,这个属于窗口内的数据。

3. Not Sent,RecipientReady to Receive:这部分是尽快发送的数据,这部分数据已经被加载到缓存中,也就是窗口中了,等待发送,其实这个窗口是完全有接收方告知的,接收方告知还是能够接受这些包,所以发送方需要尽快的发送这些包

4. Not Sent,RecipientNot Ready to Receive: 这些数据属于未发送,同时接收端也不允许发送的,因为这些数据已经超出了发送端所接收的范围

对于接收端也是有一个接收窗口的,类似发送端,接收端的数据有3个分类,因为接收端并不需要等待ACK所以它没有类似的接收并确认了的分类,情况如下

1. Received and ACKNot Send to Process:这部分数据属于接收了数据但是还没有被上层的应用程序接收,也是被缓存在窗口内

2. Received Not ACK: 已经接收并,但是还没有回复ACK,这些包可能输属于Delay ACK的范畴了

3. Not Received:有空位,还没有被接收的数据。

发送窗口和可用窗口

对于发送方来讲,窗口内的包括两部分,就是发送窗口(已经发送了,但是没有收到ACK),可用窗口,接收端允许发送但是没有发送的那部分称为可用窗口。

1. Send Window : 20个bytes 这部分值是有接收方在三次握手的时候进行通告的,同时在接收过程中也不断的通告可以发送的窗口大小,来进行适应

2. Window Already Sent: 已经发送的数据,但是并没有收到ACK。

滑动窗口原理

TCP并不是每一个报文段都会回复ACK的,可能会对两个报文段发送一个ACK,也可能会对多个报文段发送1个ACK【累计ACK】,比如说发送方有1/2/3 3个报文段,先发送了2,3 两个报文段,但是接收方期望收到1报文段,这个时候2,3报文段就只能放在缓存中等待报文1的空洞被填上,如果报文1,一直不来,报文2/3也将被丢弃,如果报文1来了,那么会发送一个ACK对这3个报文进行一次确认。

举一个例子来说明一下滑动窗口的原理:

1. 假设32~45 这些数据,是上层Application发送给TCP的,TCP将其分成四个Segment来发往internet

2. seg1 32~34 seg3 35~36 seg3 37~41 seg4 42~45 这四个片段,依次发送出去,此时假设接收端之接收到了seg1 seg2 seg4

3. 此时接收端的行为是回复一个ACK包说明已经接收到了32~36的数据,并将seg4进行缓存(保证顺序,产生一个保存seg3 的hole)

4. 发送端收到ACK之后,就会将32~36的数据包从发送并没有确认切到发送已经确认,提出窗口,这个时候窗口向右移动

5. 假设接收端通告的Window Size仍然不变,此时窗口右移,产生一些新的空位,这些是接收端允许发送的范畴

6. 对于丢失的seg3,如果超过一定时间,TCP就会重新传送(重传机制),重传成功会seg3 seg4一块被确认,不成功,seg4也将被丢弃

就是不断重复着上述的过程,随着窗口不断滑动,将真个数据流发送到接收端,实际上接收端的Window Size通告也是会变化的,接收端根据这个值来确定何时及发送多少数据,从对数据流进行流控。原理图如下图所示:

滑动窗口动态调整

主要是根据接收端的接收情况,动态去调整Window Size,然后来控制发送端的数据流量

1. 客户端不断快速发送数据,服务器接收相对较慢,看下实验的结果

a. 包175,发送ACK携带WIN = 384,告知客户端,现在只能接收384个字节

b. 包176,客户端果真只发送了384个字节,Wireshark也比较智能,也宣告TCP Window Full

c. 包177,服务器回复一个ACK,并通告窗口为0,说明接收方已经收到所有数据,并保存到缓冲区,但是这个时候应用程序并没有接收这些数据,导致缓冲区没有更多的空间,故通告窗口为0, 这也就是所谓的零窗口,零窗口期间,发送方停止发送数据

d. 客户端察觉到窗口为0,则不再发送数据给接收方

e. 包178,接收方发送一个窗口通告,告知发送方已经有接收数据的能力了,可以发送数据包了

f. 包179,收到窗口通告之后,就发送缓冲区内的数据了.

总结一点,就是接收端可以根据自己的状况通告窗口大小,从而控制发送端的接收,进行流量控制

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

本文分享自 码上修行 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 三次握手
  • 四次挥手
  • 滑动窗口
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档