tcp滑动窗口,重传 的研究,网路接收发送流程,linux查看套接字信息

1 滑动窗口机制
    滑动窗口机制,用于检测何时发生了数据包丢失,并调整数据传输率加以避免。滑动窗口机制利用数据接收方的接收窗口来控制数据流。
     tcp通过ack包来声明己方的接收窗口,tcp发送端通过对端的接收窗口 来调整自己的发送窗口。
    发送窗口的大小对性能的影响非常重要,发送窗口可以决定一次过可以发送多少字节,单位是MSS(单个TCP包最大能携带的字节)。在没有拥塞时,发送窗口越大,性能越好。所以在带宽没有限制的条件下,应该尽量增大接收窗口
    
    比如客户端正在向接收窗口大小位5000字节的服务器发送数据,客户端发送了2500字节,将服务器的缓冲空间减少到2500字节,然后再发送2000字节,进而将缓冲区减少到500字节。然后服务器发送出这些数据的确认,处理缓冲区的数据,得到可用的空缓冲区。该过程会不断的重复
    
    当一台繁忙的服务器 处理来自多个客户端的数据包时,服务器可能会缓慢地清空缓冲区,腾不出空间来接受新数据。如果没有流量控制,这将导致数据包丢失和数据损坏。幸好,当服务器太繁忙,以至不能以接收窗口宣告的速率处理数据时,它可以调整接收窗口的大小。它通过减少发送返回ACK数据包的TCP头部窗口大小值,达到这个目的
    
    

2 超时重传
    对发送方来说,当发出去的包不想往常一样得到确认了。当等待一段时间后,还是迟迟收不到,就认为这个包已经丢失了,
只能重传了。这个过程称为超时重传。
    从发出原始包到重传该包的这段时间 称为RTO

3 快速重传
    当接收方收到一个预料之外的序号时,它假设有一个数据包在传输中丢失了。为了正确地重组数据,接收方必须要得到丢失的数据包,因此它重新发送一个包含丢失数据包序号的ACK数据包,告诉发送方,我还没接收相对应序号的包
    当传输主机收到3个来自接收方的重复ACK时,它假设这个数据包确实在传输中丢失了,并立刻发送一个快速重传
    因为TCP是通过发送ACK包来 预测 下一次 接收 的包的seq,如果下次 接收的包的seq 是非预期中的,那么tcp会怀疑该包是否丢失了

4 TCP 怎么调整 拥塞时的发送窗口
    我们知道,发送窗口是收对端的接收窗口 与 网络因素影响。
    接收窗口 我们都知道,只需要 在 接收方ack 包中 指定接收窗口即可。但是网络因素呢?
    我们在 发送方维护 一个虚拟的拥塞窗口。网络对发送窗口的限制,就是通过拥塞窗口实现的。
    当连接刚刚建立的时候,发送方对网络状况一无所知。如果一口气发太多数据就可能遭遇拥塞,所以发送方把拥塞窗口的初始值定得很小。RFC得建议是2个,3个MSS
    如果发送发出去的包都得到确认,表明还没有达到拥塞点,可以增大拥塞窗口,这个阶段 触碰到拥晒点的概率比较小,所以
拥塞窗口继续增大。这个过程叫做慢启动过程。
    当然并不是一直都以这个速率增大拥塞窗口。当将拥塞窗口比较大的时候,会减慢 拥塞窗口的增加速率


5 SYN ACK FIN RST 标志位的意思
    SYN 表示同步序号(Synchronize Sequence Number)。该标识仅在三次握手建立TCP连接时有效。它提示TCP连接的服务端检查序列号编号,
    
    ACK 确认标志位,可以预测 下一个 响应包的序列号
    
    FIN   FIN 标志位用来表明连接的终结

    RST 标志用来指出连接被异常中止或拒绝连接请求

    PSH/ACK 重传数据包
    

 

6 网络包的接收流程

     当一个网络帧 到达网卡后,网卡会通过DMA方式,把这个网络包放到收包队列中;然后通过硬中断,告诉中断处理程序已经收到了网络包.

     接着,网卡中断处理程序会为网络帧分配内核数据结构(sk_buff),并将其拷贝到sk_buff缓冲区;然后再通过软中断,通知内核接收到了新的网络帧

     接下来,内核协议栈从缓冲区取出网络帧,并通过网络协议栈,从下到上逐层处理这个网络帧。比如,在链路层检查报文的合法性,找出上层协议的类型(比如IPV4还是IPV6),再去吊帧头,帧尾,然后交给网络层。

      网络层取出IP头,判断网络包下一步的走向,比如是交给上层处理还是转发。当网络层确认这个包是要发送到本机后,就会取出上层协议的类型(比如TCP 还是 UDP),去掉IP头,再交给传输层处理

     传输层取出 TCP头或者UDP头后,根据 源IP 目的IP 源端口 目的端口作为标识,找出对应的socket,并把数据拷贝到socket的接收缓存中

      所以 网络包的接收流程是:

      网卡 --> 收包队列 --> 内核缓冲区 -> linux网络协议栈处理后并把数据 拷贝到socket的接收缓存中

 

7 网络包的发送流程

        首先,应用程序调用 socket API 发送网络包

        由于这是一个系统调用,所以会陷入内核态的套接字层中。套接字层会把数据包放到socket发送缓冲区中。

        接下来,网络协议栈从socket发送缓冲区中,取出数据包;再按照TCP/IP栈,从上到下逐层处理。然后放到发送队列中。这一切完成后,会有软中断通知驱动程序:发包队列中有新的网络帧需要发送

        最后,驱动程序通过DMA,从发包队列中读出网络帧,并通过物理网卡把它发送出去

        所以 网速包发送 流程是

        socket发送缓冲区 --> 发包队列 --> 物理网卡 发送出去

 

8  查看套接字信息

      通常 我们 可以 使用 ss -nltp 查看 TCP套接字 信息

[root@izm5efwaqhukrqgsmh2vw4z ~]# ss -nltp

State Recv-Q Send-Q Local Address:Port Peer Address:Port

LISTEN 0 100 *:8011 *:* users:(("java",pid=23128,fd=45))

LISTEN 0 50 *:35919 *:* users:(("java",pid=17511,fd=15))

LISTEN 0 100 *:8080 *:* users:(("java",pid=26345,fd=48))

LISTEN 0 100 *:8081 *:* users:(("java",pid=20446,fd=44))

LISTEN 0 128 *:4369 *:* users:(("epmd",pid=7565,fd=3))

LISTEN 0 100 *:8082

 

       其中 Recv-Q 是接收队列,Send-Q 是发送队列,它们通常是0.当你发现它们不是0时,说明有网络包的堆积发生。

当然还要注意,在不同套接字状态下,它们的含义不同

         当套接字处于连接状态(Established)时,

         Recv-Q 表示套接字缓冲还没有被应用程序取走的字节数(即接收队列长度)

         而 Send-Q 表示还没有被远端主机确认的字节数(即发送队列长度)

 

         当套接字处于监听状态(Listening)时,

          Recv-Q 表示 syn backlog 的当前值

          而 Send-Q 表示最大的 syn backlog 值

          而 syn backlog 是 TCP 协议栈中的半连接队列长度,

          相应的也有一个全连接队列 (accept queue),它们都是维护TCP状态的重要机制

 

         所谓半连接,就是还没有完成TCP 三次握手的连接,连接只进行了一半,而服务器收到了客户端的SYN包后,就会把

这个连接放到连接队列中,然后再向客户端发送SYN+ACK包

 

        而全连接,则是指服务器接收到了客户端的ACK,完成了三次握手,然后就会把这个连接挪到全连接队列中。这些全

连接中的套接字,还需要再被accept()系统调用取走,这样,服务器就可以开始真正处理客户端的请求了

 

 

 

 

参考资料

     网络分析艺术

     wireshark数据包实战

 


 

你可能感兴趣的:(网络)