it_worker365

   ::  ::  ::  ::  :: 管理

TCP特点:

提供可靠的,保证数据能够准确的到达目的地,如果不能,需要检测发现并重传

流量可控,管理发送数据的频率,不超过设备的承载能力

滑动窗口:https://blog.csdn.net/wdscq1234/article/details/52444277   http://blog.chinaunix.net/uid-26275986-id-4109679.html

滑动窗口,连接建立时,各端分配一块缓冲区用来存储接收的数据,并将缓冲区尺寸发送给另一端

接收方发送的确认信息中包含了自己剩余的缓冲区尺寸,剩余缓冲区看空间的数量叫做窗口

 

 

 

 

 

 

#1 发送成功并已经确认,位于窗口之外,窗口内循序最低的被确认后,窗口进行合拢同时接收新的待发送数据

#2 发送未确认,窗口内数据,发送出去但没收到ack

#3 已经被加载到缓存中,在窗口中等待发送,这部分接收方已经告知能接受这些数据,应尽快发送

#4 未发送,接收端不允许发送,因为超出了接收端可接收的范围

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

1.  Received and ACK Not 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 seg2 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,收到窗口通告之后,就发送缓冲区内的数据了.

 

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

TCP 建立连接:

From: http://www.cnblogs.com/Jessy/p/3535612.html

各个状态的意义如下: 
LISTEN - 侦听来自远方TCP端口的连接请求; 
SYN-SENT -在发送连接请求后等待匹配的连接请求; 
SYN-RECEIVED - 在收到和发送一个连接请求后等待对连接请求的确认; 
ESTABLISHED- 代表一个打开的连接,数据可以传送给用户; 
FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;
FIN-WAIT-2 - 从远程TCP等待连接中断请求; 
CLOSE-WAIT - 等待从本地用户发来的连接中断请求; 
CLOSING -等待远程TCP对连接中断的确认; 
LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认; 
TIME-WAIT -等待足够的时间以确保远程TCP接收到连接中断请求的确认; 
CLOSED - 没有任何连接状态;

TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接,如图1所示。

(1)第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_SEND状态,等待服务器B确认。

(2)第二次握手:服务器B收到SYN包,必须确认客户A的SYN(ACK=j+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器B进入SYN_RECV状态。

(3)第三次握手:客户端A收到服务器B的SYN+ACK包,向服务器B发送确认包ACK(ACK=k+1),此包发送完毕,客户端A和服务器B进入ESTABLISHED状态,完成三次握手。

完成三次握手,客户端与服务器开始传送数据。

确认号:其数值等于发送方的发送序号 +1(即接收方期望接收的下一个序列号)。

 

 

 

 

 

 

 

TCP关闭连接:

 

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

 TCP的连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake)。客户端或服务器均可主动发起挥手动作,在socket编程中,任何一方执行close()操作即可产生挥手操作。

(1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。 

(2)服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。 

(3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A。 

(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。 

TCP采用四次挥手关闭连接如图2所示。

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
TCP协议的连接是全双工连接,一个TCP连接存在双向的读写通道。 
简单说来是 “先关读,后关写”,一共需要四个阶段。以客户机发起关闭连接为例:
1.服务器读通道关闭
2.客户机写通道关闭
3.客户机读通道关闭
4.服务器写通道关闭
关闭行为是在发起方数据发送完毕之后,给对方发出一个FIN(finish)数据段。直到接收到对方发送的FIN,且对方收到了接收确认ACK之后,双方的数据通信完全结束,过程中每次接收都需要返回确认数据段ACK。
详细过程:
    第一阶段   客户机发送完数据之后,向服务器发送一个FIN数据段,序列号为i;
    1.服务器收到FIN(i)后,返回确认段ACK,序列号为i+1,关闭服务器读通道;
    2.客户机收到ACK(i+1)后,关闭客户机写通道;
   (此时,客户机仍能通过读通道读取服务器的数据,服务器仍能通过写通道写数据)
    第二阶段 服务器发送完数据之后,向客户机发送一个FIN数据段,序列号为j;
    3.客户机收到FIN(j)后,返回确认段ACK,序列号为j+1,关闭客户机读通道;
    4.服务器收到ACK(j+1)后,关闭服务器写通道。
这是标准的TCP关闭两个阶段,服务器和客户机都可以发起关闭,完全对称。
FIN标识是通过发送最后一块数据时设置的,标准的例子中,服务器还在发送数据,所以要等到发送完的时候,设置FIN(此时可称为TCP连接处于半关闭状态,因为数据仍可从被动关闭一方向主动关闭方传送)。如果在服务器收到FIN(i)时,已经没有数据需要发送,可以在返回ACK(i+1)的时候就设置FIN(j)标识,这样就相当于可以合并第二步和第三步。

TCP状态转移:https://kb.cnblogs.com/page/209100/

 

 

posted on 2018-09-12 09:28  it_worker365  阅读(132)  评论(0编辑  收藏  举报