zoukankan      html  css  js  c++  java
  • TCP 协议相关

    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/

     

  • 相关阅读:
    软考解析:2014年上半年下午试题
    软考解析:2014年下半年下午试题
    软考解析:2015年下半年下午试卷
    软考解析:2015年上半年下午试卷
    怎样完善和推广自己的理论模型?
    怎样完善和推广自己的理论模型?
    Android开发——常见的内存泄漏以及解决方案(一)
    聊聊Android5.0中的水波纹效果
    JVM——自定义类加载器
    JVM——Java类加载机制总结
  • 原文地址:https://www.cnblogs.com/it-worker365/p/9428430.html
Copyright © 2011-2022 走看看