发送tcp的时候,数据包是如何拷贝的
Posted honpey
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了发送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
以上是关于发送tcp的时候,数据包是如何拷贝的的主要内容,如果未能解决你的问题,请参考以下文章