LINUX网络收发原理、网络配置及常见错误【好文】

本文详细阐述了网络请求的工作原理,包括数据包的发送与接收流程,并介绍了Linux下的网络配置命令,如ifconfig、route、traceroute等。此外,还列举了常见的网络配置错误及其解决方法。

 一:网络请求原理

(1)收发流程

假定主机A的IP地址是192.168.1.1,主机B的IP地址是192.168.1.2,都在同一子网内,则当你在主机A上运行“Ping 192.168.1.2”后,都发生了些什么呢?


1.首先,Ping命令会构建一个固定格式的ICMP请求数据包,然后由ICMP协议将这个数据包连同地址“192.168.1.2”一起交给IP层协议

2.IP层协议将以地址“192.168.1.2”作为目的地址,本机IP地址作为源地址,加上一些其他的控制信息,构建一个IP数据包,并在一个映射表(映射表由ARP实现。ARP(Address Resolution Protocol)是地址解析协议,是一种将IP地址转化成物理地址的协议)中查找出IP地址192.168.1.2所对应的物理地址(也叫MAC地址,熟悉网卡配置的朋友不会陌生,这是数据链路层协议构建数据链路层的传输单元——帧所必需的),一并交给数据链路层。

3.数据链路层构建一个数据帧,目的地址是IP层传过来的物理地址,源地址则是本机的物理地址,还要附加上一些控制信息,依据以太网的介质访问规则,将它们传送出去。

4.主机B收到这个数据帧后,先检查它的目的地址,并和本机的物理地址对比,如符合,则接收;否则丢弃。
5.主机B接收后检查该数据帧,将IP数据包从帧中提取出来,交给本机的IP层协议。同样,IP层检查后,将有用的信息提取后交给ICMP协议,后者处理后,马上构建一个ICMP应答包,发送给主机A,其过程和主机A发送ICMP请求包到主机B一模一样。

以上就是大致的网络收发流程。

(2)网卡初始化

而上文中黑体字IP层协议又是什么时候开始处理网络数据包的呢?

这得先说下网络驱动,即网卡。

网络驱动收包大致有3种情况:
no NAPI:mac每收到一个以太网包,都会产生一个接收中断给cpu,即完全靠中断方式来收包缺点是当网络流量很大时,cpu大部分时间都耗在了处理mac的中断。
netpoll:在网络和I/O子系统尚不能完整可用时,模拟了来自指定设备的中断,即轮询收包。缺点是实时性差。
NAPI   :采用中断+  轮询的方式:mac收到一个包来后会产生接收中断,但是马上关闭。直到收够了netdev_max_backlog(一个配置的变量值)个包(默认300),或者收完mac上所有包后,才再打开接收中断通过sysctl来修改 net.core.netdev_max_backlog 或者通过proc 修改/proc/sys/net/core/netdev_max_backlog

 

不管采用哪种方式,中断还是轮询,linux都是在内核初始化时进行网卡初始化的,调用如下

start_kernel()    

 

  --> rest_init()

 

    --> do_basic_setup()            

 

     --> do_initcall()               

 

      -->net_dev_init()

 

并在net_dev_init()中进行网络包的发送和监听的处理。

(3)网卡初始化的流程:从底到上分析

先上一张网络栈的层次结构图:(注:该图片摘自《Linux内核网络栈源代码情景分析》)

 

 

1、网络接口层

* 硬件监听物理介质,进行数据的接收,当接收的数据填满了缓冲区即“网卡初始化”中NAPI部分提到的netdev_max_backlog,硬件就会产生中断,中断产生后,系统会转向中断服务子程序。

* 在中断服务子程序中,数据会从硬件的缓冲区复制到内核的空间缓冲区,并包装成一个数据结构(sk_buff),然后调用对驱动层的接口函数netif_rx()将数据包发送给链路层。该函数的实现在net/inet/dev.c中,(在整个网络栈实现中dev.c文件的作用重大,它衔接了其下的驱动层和其上的网络层,可以称它为链路层模块的实现)

2、网络层
* 就以IP数据包为例来说明,那么从链路层向网络层传递时将调用ip_rcv函数。该函数完成本层的处理后会根据IP首部中使用的传输层协议来调用相应协议的处理函数。

UDP对应udp_rcv、TCP对应tcp_rcv、ICMP对应icmp_rcv、IGMP对应igmp_rcv(虽然这里的ICMP,IGMP一般成为网络层协议,但是实际上他们都封装在IP协议里面,作为传输层对待)

3、传输层

如果在IP数据报的首部标明的是使用TCP传输数据,则在上述函数中会调用tcp_rcv函数。该函数的大体处理流程为:

“所有使用TCP 协议的套接字对应sock 结构都被挂入tcp_prot 全局变量表示的proto 结构之sock_array 数组中,采用以本地端口号为索引的插入方式,所以当tcp_rcv 函数接收到一个数据包,在完成必要的检查和处理后,其将以TCP 协议首部中目的端口号(对于一个接收的数据包而言,其目的端口号就是本地所使用的端口号)为索引,在tcp_prot 对应sock 结构之sock_array 数组中得到正确的sock 结构队列,在辅之以其他条件遍历该队列进行对应sock 结构的查询,在得到匹配的sock 结构后,将数据包挂入该sock 结构中的缓存队列中(由sock 结构中receive_queue 字段指向),从而完成数据包的最终接收。”

4、应用层

当用户需要接收数据时,首先根据文件描述符inode得到socket结构和sock结构,然后从sock结构中指向的队列recieve_queue中读取数据包,将数据包COPY到用户空间缓冲区。数据就完整的从硬件中传输到用户空间。这样也完成了一次完整的从下到上的传输。

 

以上就是从ping主机的案例到网络收发的底层原理的一个讲解。可见网络收发是贯穿了整个网络协议栈的每个部分的,当网络配置错误时,从完整协议栈流程中去分析错误点是个非常好的方法。下面开始说明网络配置及常见错误。

 

二、网络配置命令

 

LINUX下的网络配置命令是ifconfig类似于WINDOWS命令行中的ipconfig。可以使用ifconfig命令来配置并查看网络接口的配置情况。

 

1、如:
(1) 配置eth0的IP地址, 同时激活该设备。
#ifconfig eth0 192.168.1.10 netmask 255.255.255.0 up
(2) 配置eth0别名设备eth0:1的IP地址,并添加路由。
#ifconfig eth0 192.168.1.3
#route add –host 192.168.1.3 dev eth0:1
(3) 激活设备。
#ifconfig eth0 up
(4) 禁用设备。
#ifconfig eth0 down
(5) 查看指定的网络接口的配置。
#ifconfig eth0
(6) 查看所有的网络接口配置。
#ifconfig

 

2、 route
可以使用route命令来配置并查看内核路由表的配置情况。
例如: 
(1) 添加到主机的路由。
#route add –host 192.168.1.2 dev eth0:0
#route add –host 10.20.30.148 gw 10.20.30.40
(2) 添加到网络的路由。
#route add –net 10.20.30.40 netmask 255.255.255.248 eth0
#route add –net 10.20.30.48 netmask 255.255.255.248 gw 10.20.30.41
#route add –net 192.168.1.0/24 eth1
(3) 添加默认网关。
#route add default gw 192.168.1.1
(4) 查看内核路由表的配置。
#route
(5)删除路由。
#route del –host 192.168.1.2 dev eth0:0
#route del –host 10.20.30.148 gw 10.20.30.40
#route del –net 10.20.30.40 netmask 255.255.255.248 eth0
#route del –net 10.20.30.48 netmask 255.255.255.248 gw 10.20.30.41
#route del –net 192.168.1.0/24 eth1
#route del default gw 192.168.1.1
对于1和2两点可使用下面的语句实现:
Ifconfig eth0 172.16.19.71 netmask 255.255.255.0
Route 0.0.0.0 gw 172.16.19.254
Service network restart

 

3、 traceroute
可以使用traceroute命令显示数据包到达目的主机所经过的路由。
例如:
#traceroute x

 

4、 ping 
可以使用ping 命令来测试网络的连通性。
例如:
#ping x
#ping –c 4 192.168.1.12

 

5、 netstat
可以使用netstat命令来显示网络状态信息。
例如:
(1) 显示网络接口状态信息。
#netstat –i
(2) 显示所有监控中的服务器的Socket和正使用Socket的程序信息。
#netstat –lpe
(3) 显示内核路由表信息。
#netstat –r
#netstat –nr
(4) 显示TCP/UDP传输协议的连接状态。
#netstat –t
#netstat –u

 

6、 hostname
可以使用hostname命令来更改主机名。例如;
#hostname myhost

 

7、 arp
可以使用arp命令来配置并查看arp缓存。例如:
(1) 查看arp缓存。
#arp
(2) 添加一个IP地址和MAC地址的对应记录。
#arp –s 192.168.33.15 00:60:08:27:CE:B2
(3) 删除一个IP地址和MAC地址的对应缓存记录。
#arp –d192.168.33.15

 

三.Linux常见发布型号的网络配置文件:
(1)Redhat/Centos网络配置文件地址:/etc/sysconfig/network-scripts/ifcfg-eth0

文件内容及含义:

#网卡名字

DEVICE=eth0

#mac地址

HWADDR=08:00:27:a0:87:a4

#网络连接类型
TYPE=Ethernet

#网卡设备号
UUID=ce25ae0c-572f-4b81-a5a7-f96a5387690b

#网卡是否开机启动
ONBOOT=yes

#设备eth0是否可以由Network Manager图形管理工具托管

NM_CONTROLLED=yes

#ip获取方式
BOOTPROTO=static

#ip地址

IPADDR=192.168.0.210

#网关
NETMASK=255.255.255.0

#广播地址
BROADCAST=192.168.0.255

(2)Ubuntu网络配置文件地址: /etc/network/interfaces

文件内容如下:

#ping 127.0.0.1时的请求网卡,即回环地址
auto lo
iface lo inet loopback
auto eth0
#如果是自动获取ip,添加
iface eth0 inet dhcp
#如果是手动配置ip,以下同(1)的配置

iface eth0 inet static
address xxx.xxx.xxx.xxx
netmask xxx.xxx.xxx.xxx
network xxx.xxx.xxx.xxx
boardcast xxx.xxx.xxx.xxx
gateway xxx.xxx.xxx.xxx

 

四、网络配置常见错误及解决

网络检查完整流程如下:

1.执行service network restart或者ping 127.0.0.1看能否成功

如果不成功就是本地网卡配置错误,根据本文第一节第二部分中的网络配置文件参数去检查

1.1 mac 是否合法

虚拟机clone后mac地址还是跟母版系统一样,这样会冲突,所以需要更新mac地址

rm -f /etc/udev/rules.d/70-persistent-net.rules

reboot

1.2 网关是否跟路由器IP一致,虚拟机要检查是否跟宿主机网关一致

1.3 子网掩码是否跟宿主机一致,保证在同一个网段

1.4 IP是否合法

  1.4.1 IP段必须在2-154之间,0,1,255都是特殊点,超出255更加不合法(我有一次就设置成了192.168.1.300...)

  1.4.2 IP是否跟其他主机重复

2. 检查局域网主机

2.1防火墙是否开启,导致ICMP等协议无法访问

2.2 IPSec是否开启导致无法访问

2.3 网线是否没插好,在虚拟机中即网络连接方式是否没有配好

比如选择桥接方式,虚拟机所桥接的网卡一定是宿主机在用的能联网的网卡,比如下图中一定要选择第一个

同时,选择宿主机上可用网卡之后,要设置其为允许其他计算机连接,如下图

这样才能有一个可用的上网通道。

3.Internet访问时检查DNS配置

vi /etc/resolv.conf

添加 nameserver 8.8.8.8保证域名可被解析

 

还不行的时候检查下是不是网费欠费了。。。

 

以下为常见错误

(1)Request timed out

系统可以访问到主机,但是在响应时间内没有收到响应。

(2)Destination host unreachable

系统不存在到达远程主机的合法路由。要么是本机网络环境没配置好,要么是远程主机无法访问。

2.1 当虚拟机ping不通宿主机和网关:虚拟机与宿主机及网关之间没有建立通路,可以查看虚拟机与宿主机连接方式能否连通;

2.2 当虚拟机ping仅不通网关:虚拟机与网关之间没有建立通路,如果虚拟机与宿主机的连接方式没有问题,有可能是虚拟机的网卡冲突,

请关闭其他网卡并重启网络试下

(3)虚拟机宿主机可以互相ping通,但是ping外网时出现 unknow host

首先查看是否设置DNS,其次看下是否设置网关,网关是否与宿主机一致

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值