zoukankan      html  css  js  c++  java
  • 发送tcp的时候,数据包是如何拷贝的

    发送数据包的时候,用户态的数据包是如何拷贝到内核的kiovec

    msghd 结构体

    icmp是走sock吗?

    每一个skb_buffer的大小都是固定的吗?所以有skb_available这样的函数

    1883 /**             
    1884  *  skb_availroom - bytes at buffer end
    1885  *  @skb: buffer to check
    1886  *      
    1887  *  Return the number of bytes of free space at the tail of an sk_     buff
    1888  *  allocated by sk_stream_alloc()
    1889  */
    1890 static inline int skb_availroom(const struct sk_buff *skb)
    1891 {           
    1892     if (skb_is_nonlinear(skb))
    1893         return 0; 
    1894 
    1895     return skb->end - skb->tail - skb->reserved_tailroom;
    1896 }  
    1897         
    

     skb->end和skb->tail有什么区别?end tail reserved_room

    end 和 tail的设置位于函数__alloc_skb

    在分配skb的时候怎么把下层协议的数据全部都考虑在内?

    skb_reset_tail_pointer函数中会把函数data和head都是函数头

    <head, tail> head是有效数据的头, tail是有效数据尾,是想相对偏移!相对偏移!相对偏移!end是整个skb的最后

    看下是如何发送一个数据包的,

      skb = alloc_skb_fclone(size + sk->sk_prot->max_header, gfp);
    其中sk->sk_prot->max_header = MAX_TCP_HEADER

    #define MAX_TCP_HEADER  (128 + MAX_HEADER)

     150 #if !IS_ENABLED(CONFIG_NET_IPIP) && !IS_ENABLED(CONFIG_NET_IPGRE) &&
     151     !IS_ENABLED(CONFIG_IPV6_SIT) && !IS_ENABLED(CONFIG_IPV6_TUNNEL)
     152 #define MAX_HEADER LL_MAX_HEADER
     153 #else
     154 #define MAX_HEADER (LL_MAX_HEADER + 48)
     155 #endif

     138 #if defined(CONFIG_HYPERV_NET)
     139 # define LL_MAX_HEADER 128
     140 #elif defined(CONFIG_WLAN) || IS_ENABLED(CONFIG_AX25)
     141 # if defined(CONFIG_MAC80211_MESH)
     142 #  define LL_MAX_HEADER 128
     143 # else
     144 #  define LL_MAX_HEADER 96
     145 # endif
     146 #else
     147 # define LL_MAX_HEADER 32
     148 #endif
    

     用户态的数据都是在内核中有一份拷贝, 每创造一个skb,就把这个skb放到了sock的send_list中去

    tcp_write_xmit 函数

    顺序问题;丢包问题;链接维护;流量控制;拥塞控制;

    顺序问题、丢包问题、流量问题都是通过滑动窗口来解决的。这三个问题都是接收端强相关,是因为发送端按部就班地发送,接收端收到的顺序是错乱的,发送端把包发送出去了,是接收端没有接收到包(另外ack包也有可能丢失),流量问题是接收端主动向发送端上报我的接收窗口,从而达到了流量控制的目的; 但是解决方法在发送端解决:(超时重传|快速重传|SACK)。所以丢包和顺序都是通过滑动窗口来解决的!在对包的确认中会携带一个窗口的大小!

    拥塞控制发送端相关。是因为发送窗口,才会导致网络拥塞啊。

    tcp_transmit_skb中是真正发送;

    在发送数据包之前什么会导致数据包下发失败呢?发送窗口不允许

    有几个重要的概念: tso(tcp segment offload), mss, RTT(round trip time)

    内核里面是怎么计算rtt的?超时重传会用到RTT,超时重传时使用!

    mss(max segment size)

    拥塞窗口:snd_cwnd

    滑动窗口是TCP协议中的核心,顺序、丢包都是通过滑动窗口来指导,但是在这个窗口之内的发送的速率呢?确定过了滑动窗口之后,发送端当然可以一股脑把数据全部都送出去啊,此时肯定不会把接收端打满,但是会把网络打满!所以会把网络打满!会把网络打满!所以给了你一个quota,怎么用这个quota,至于你怎么用那就是你的事情了!使用网络拥塞算法解决网络拥堵的问题呀!

    函数中:tcp_cwnd_test tcp_packages_in_flight


     

  • 相关阅读:
    简单理解同步与异步
    Python3.x 安装Scrapy框架
    Python命名规范
    python 02/100例
    raw_input与input的区别
    二叉排序树
    串和广义表
    数据结构整理 第一章
    时间复杂度
    Music
  • 原文地址:https://www.cnblogs.com/honpey/p/9191771.html
Copyright © 2011-2022 走看看