《深入理解Linux网络》读书笔记4
原创- 2023-12-21 15:19:53
- 1246
本篇目录
本机网络IO的内核执行流程
由图可以得出几个结论:
1、127.0.0.1本机网络IO需要经过网卡吗?
不需要,即使拔掉网卡,本机网络还是可以正常使用的
2、数据包在内核中的走向是啥?
-
和外网发送相比流程上有啥差别?
总的来说,本机网络IO和跨级网络IO比起来,节约了驱动上的一些开销。发送数据不需要进RingBuffer
的驱动队列,直接把skb
传给接受协议栈(通过软中断)。但是在内核其他组件上,并没有节约。系统调用、协议栈(传输层、网络层等)、设备子系统整个走了一遍。连“驱动”程序都走了(虽然对于回环设备来说,只是一个纯软件虚拟出来的东西)。所以即使是本机网络IO,也不应滥用。
- 如果想在本机网络IO上绕开协议栈的开销,需要动用
eBPF
。使用eBPF
的sockmap
和sk redirect
可以达到真正不走协议栈的目的。
3、访问本机服务时,使用127.0.0.1能比使用本机IP(例如192.168.x.x)更快吗?
两者并无区别,都是走虚拟的环回设备IO。因为内核在设置IP的时候,把所有的本机IP都初始化到local路由表里了,类型写死了是RTN_LOCA
L。在后面的路由项选择的时候发现类型是RTN_LOCAL
就会选择IO设备。
为啥服务端程序都需要先listen一下?
因为内核在相应listen
调用的时候是创建了半连接、全连接两个队列,这两个队列是三次握手中很重要的数据结构,有了他们服务端才能正常响应来自客户端的三次握手。所以服务端程序都需要先listen
一下。
半连接队列和全连接队列长度咋确定?
服务端在执行listen的时候确定好了半连接队列和全连接队列的长度。
-
对于半连接队列来说,其最大长度是 min(
backlog
,somaxconn
,tcp_max_syn_backlog
) + 1再向上取整到2的N次幂,但最小不能小于16。如果需要加大半连接队列长度,则需要一并考虑backlog
,somaxconn
和tcp_max_syn_backlog
。
-
对于全连接队列来说,其最大长度是
listen
时传入的backlog
和net.core.somaxconn
之间较小的那个值。如果需要加大全连接队列的长度,则需要调整backlog
和somaxconn
。
一个客户端端口可以同时用在两条连接上吗?
1、connect
调用在选择端口的时候如果端口没有被用过那么就是可用的。但如果端口是被用过的,并不是说这个端口不能用了。
2、如果用过,接下来进一步判断新连接和老连接四元组是否完全一致,如果不完全一致,该端口仍然可用。例如5000这个端口下完全可用于下面两条不同的连接。
-
连接一:192.168.101.1:5000 192.168.101.1:8090
-
连接二:192.168.101.1:5000 192.168.101.1:8091
3、在保证四元组不相同的情况下,一个端口完全可以用在两条,甚至更多条的连接上。