Linux网络管理

作者:

在

ip网络通信类型补充:

在ipv4地址下:

​ ● 单播(Unicast)平时上网与服务器之间1v1双向单播

​ ● 广播(Broadcast) 网络广播一般是255.255.255.255或某个子网主机位全为1的网段,广播必须接收

​ ● 组播(Multicast) D类地址可用于组播,组播是接收方自动加入

在ipv6地址下:

没有广播了,只有任播(anycast)

子网掩码补充

如何通过子网掩码划分,将192.168.1.0/24的网络,划分成2个子网?划分成4个呢?

先尝试将子网掩码往后移动一位

1100 0000.1010 1000.0000 0001.0|000 0000
1111 1111.1111 1111.1111 1111.1|000 0000  (子网掩码是255.255.255.128)

# 掩码后移之后,得到新的两个网络,主机位全0代表网络号
1100 0000.1010 1000.0000 0001.0|000 0000  (192.168.1.0/25)
1100 0000.1010 1000.0000 0001.1|000 0000  (192.168.1.128/25)

#1100 0000.1010 1000.0000 0001.10|00 0000(192.168.1.128/26)
#1100 0000.1010 1000.0000 0001.11|00 0000(192.168.1.192/26)
#1111 1111.1111 1111.1111 1111.11|00 0000

# 广播地址为主机位全为1,因此两个网络各自的广播地址为
1100 0000.1010 1000.0000 0001.0|111 1111  (192.168.1.127)
1100 0000.1010 1000.0000 0001.1|111 1111  (192.168.1.255)

# 各自子网可容纳的主机数
1100 0000.1010 1000.0000 0001.0|000 0001 - 1100 0000.1010 1000.0000 0001.0|111 1110   (192.168.1.1   - 192.168.1.126)
1100 0000.1010 1000.0000 0001.1|000 0001 - 1100 0000.1010 1000.0000 0001.1|111 1110   (192.168.1.129 - 192.168.1.254)

得到如下表格中的信息

子网网络地址范围广播地址
第1个 /25192.168.1.0/250 ~ 127192.168.1.127
第2个 /25192.168.1.128/25128 ~ 255192.168.1.255

这样划分之后,那这两个子网内部设备不需要经过路由转发,因为在同一个局域网直接通过arp协议广播就可以找到对方;

如果192.168.1.0/25内部的某个机器,需要与192.168.1.128/25内部的某个机器通信,就需要发给路由器了;

那主机如何判断目标地址是否与自己在一个局域网内部呢?非常简单:目标ip&子网掩码=自己的网段 满足等式就在一个局域网,否则不在。

ARP协议补充

路由器arp协议寻找目标设备目标设备arp回答ipconfig /all 查看
imgimgimg

==总结==:

image-20260725135418359

image-20260725135444503


DHCP补充

自己尝试一下dhcp获取ip地址,并抓取dhcp报文

# 安装tcpdump,linux抓包工具
yum install tcpdump

# -i any 指定监听的网卡
# -n    不解析主机名,默认情况下 tcpdump 会尝试把 IP 地址反向解析成域名
# port 67 or port 68    过滤条件
# 67 DHCP 服务端监听端口
# 68 DHCP 客户端监听端口
# -w dhcp_capture.pcap  可以使用wireshark打开
tcpdump -i any -n port 67 or port 68 -w dhcp_capture.pcap

# 新开一个shell
# 删除保持通过dhcp获取的缓存ip信息
cd /var/lib/NetworkManager/
rm internal-7e7958c9-d951-3deb-af85-4459aa3dbe39-ens160.lease # 这个文件里面存放了dhcp获取的ip地址
nmcli connection down ens160 && sudo nmcli connection up ens160

image-20260727183344713

自己设置ip地址

image-20260727184714833

抓包文件示例:dhcp_capture.pcap

由抓包报文可以看出,dhcp基于udp协议,并且是应用层协议

网关(路由器)(==gateway==)

image-20260727182713963

image-20260727182731009

DNS域名解析补充

​ 1. linux中/etc/hosts也保存了主机的域名映射关系

[root@192 ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
# 可以尝试将www.baidu.com 解析到127.0.0.1上

# 此文件保存了dns服务器地址,默认是网关地址
[root@192 ~]# cat /etc/resolv.conf
# Generated by NetworkManager
search localdomain
nameserver 192.168.18.2
# 可以尝试去掉,或者改成114.114.114.114,之后ping www.baidu.com将无法联通

​ 2. dns解析相关的命令

ping www.baidu.com #可以触发dns解析
# 需要安装bind的工具包
yum install bind-utils
dig www.baidu.com  #可以查看详细解析记录
nslookup www.baidu.com  # 也可以查看详细解析记录

​ 3. 域名购买和配置

​ ● 可以去阿里云购买

​ ● 域名解析怎么配置

imgimg

配置网络参数补充

改ip参数和dns参数

vim /etc/NetworkManager/system-connections/ens160.nmconnection 
[connection]
id=ens160
uuid=7e7958c9-d951-3deb-af85-4459aa3dbe39    
type=ethernet
autoconnect-priority=-999
interface-name=ens160
timestamp=1781681830

[ethernet]                                    ← 保持不变

[ipv4]
method=manual                                  ← 🔴 改:manual
address1=192.168.18.130/24,192.168.18.2        ← 🟢 新增
dns=192.168.18.2;114.114.114.114               ← 🟢 新增

[ipv6]
addr-gen-mode=eui64
method=ignore                                

[proxy]          

#使用nmcli重新刷新配置并重启网卡
nmcli conn reload # 重载配置
nmcli conn down ens160  # 断开连接
nmcli conn up ens160  # 重新连接                       

​ 4. 为了便于使用常常的nmcli命令,我们可以安装bash提示包,之后使用tab可以获取命令提示

dnf install -y bash-completion
source /etc/profile.d/bash_completion.sh# 或者关闭终端重新进入

​ 5. 如果想让网卡物理断开,请使用ip link

# 直接拔掉网卡的“电源”
ip link set ens160 down 

​ 6. nmcli/nmtui和network以及ens160物理网卡之间的关系

  用户 
   │
   ▼ 发出指令 (例如: nmcli conn up ens160)
 控制器 [ nmcli / nmtui ]
   │
   ▼ 
 管理者 [ NetworkManager 服务 (后台进程) ]
   │
   ▼ 擦除/写入 IP,开启/关闭状态
 Linux 系统内核 (Kernel) ───► 看到的效果就是 [ ip a ] 里的状态变化
   │
   ▼
 物理/虚拟网卡硬件 (ens160)

[root@localhost ~]# systemctl stop NetworkManager
[root@localhost ~]# nmcli conn down ens160
错误:网络管理器(NetworkManager)未运行。
[root@localhost ~]#

image-20260727210514621

==注意==: 只要Networkmanager中断了,nmcli程序就用不了

​ 7. nmcli命令中的up详解

[root@localhost ~]# nmcli connection add type ethernet ifname ens160 con-name dhcp_ens160   # con-name不作为唯一id,uuid是唯一区分的key
连接 "dhcp_ens160" (91641ede-2ff8-419f-84c9-09be1de79c78) 已成功添加。
[root@localhost ~]# nmcli conn show
NAME         UUID                                  TYPE      DEVICE
ens160       7e7958c9-d951-3deb-af85-4459aa3dbe39  ethernet  ens160
有线连接 1   80fc7e2a-c7ac-3604-939b-3cef2431af69  ethernet  ens224
lo           4627f296-ae4f-43c9-9b77-b8929460b955  loopback  lo
dhcp_ens160  721ec306-fde4-496c-9687-07e11a896b63  ethernet  --
[root@localhost ~]# nmcli conn up 721ec306-fde4-496c-9687-07e11a896b63
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/4)
[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:14:8e:67 brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    inet 192.168.18.129/24 brd 192.168.18.255 scope global dynamic noprefixroute ens160
       valid_lft 1797sec preferred_lft 1797sec
    inet6 fe80::5eb6:76ae:6991:2649/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: ens224: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:14:8e:71 brd ff:ff:ff:ff:ff:ff
    altname enp19s0
    inet 192.168.199.128/24 brd 192.168.199.255 scope global dynamic noprefixroute ens224
       valid_lft 1735sec preferred_lft 1735sec
    inet6 fe80::632c:8843:174f:955a/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

[root@localhost ~]# nmcli connection delete dhcp_ens160 
成功删除连接 "dhcp_ens160" (721ec306-fde4-496c-9687-07e11a896b63)。

==总结==:

image-20260727135726435

image-20260727135747155


​ 8. MTU三层网络层数据包最大传输单元,MTU限定单IP包体积。过大丢包/分片,过小浪费带宽


网络基础知识

OSI七层模型

img

OSI是理论标准,TCP/IP是事实标准,五层是工程和教学的折中,更常用。每一层的唯一标识如下

数据链路层——MAC地址

网络层——IP地址传输层——端口号应用层——PID

一个就简单路由器过程示例

img

img

数据包流转每一层所干的事情

img

网络分层动图

1703522738665.gif

img

tcp报文格式

imgimg

使用wireshark抓取tcp数据包分析一下,按照报文格式,理解大端字节序和小端字节序。

由此可见,什么是网络协议工程师

image-20260728192507699

udp和tcp对比

img

对比维度TCPUDP
连接状态面向连接(需三次握手建立链路)无连接(直接发送,无需握手)
可靠性高(确认机制、超时重传、校验和)低(只做基础校验,丢包不重传)
数据顺序保证有序(按字节流编号,乱序重组)不保证(先发的可能后到,应用层自己处理)
流量/拥塞控制有(根据网络状况动态调整发送速度)无(发得快不快,完全看应用层,网络堵了照发)
传输效率较低(头部开销大,20字节,且需维护状态)极高(头部仅8字节,处理简单)
收发模式全双工(可同时收发)支持一对一、一对多、多对多(广播/组播)
适用场景文件传输、网页浏览、邮件、数据库实时音视频、直播、在线游戏、DNS查询

==总结==:

关键点:

  • TCP 把数据看成连续的字节流,没有”消息边界”
  • 你发 3 次(100+200+50),接收端可以 1 次收完 350 字节
  • 也可以分 10 次收,每次收一部分
  • 发多少次 ≠ 收多少次

关键点:

  • UDP 保留应用层发送的完整报文边界
  • 发 3 次,收 3 次,一一对应
  • 一次 recvfrom 只能读到一个完整报文
  • 如果接收缓冲区小于报文大小,多余数据会被丢弃

==粘包与拆包==:

TCP “粘包” 问题详解

什么是粘包?

text

发送端发了 3 次:
第一次: "Hello"
第二次: "World"
第三次: "!"

接收端 recv 一次读到: "HelloWorld!"

3 次发送,1 次收到,数据粘在一起了 → 粘包

还有”拆包”

text

发送端发一次: "HelloWorld!"
接收端 recv 两次:
第一次读到: "Hello"
第二次读到: "World!"

1 次发送,多次收到 → 拆包

统称”粘包/拆包问题”

本质原因:TCP 是流式协议,没有消息边界。

解决方案(应用层自己定边界)

方案 实现方式 示例
固定长度 每个消息固定大小 每次发 1024 字节,不足补 0
分隔符 用特殊字符分隔 如 HTTP 用 rnrn,用 n
长度字段 消息头带长度 4 字节头 + 变长 body(最常用)

tcp三次握手

img

tcp四次挥手

img






传输层状态查看相关命令

端口号

内核在传递网络数据包过程中,定位进程的唯一标识就是就口号,所以如果是网络服务程序,启动时必须绑定一个固定的端口号。

启动一个python server,默认端口使用了5000,也就意味着,当客户端使用curl http://192.168.18.129:5000,http应用层数据包达到linux系统后,操作系统会首先寻找监听在5000端口的应用程序,如果没有直接丢弃。如果有,再去查询绑定ip,如果进程绑定的是0.0.0.0包含所有ip,内核就将数据包交给他。如果进程绑定的是精确的ip,例如192.168.18.129,也可交个他。如果数据包目的ip与绑定的不同,丢弃。

# 指定具体的ip和端口号
[root@localhost ~]# python3.14 -m http.server -b 192.168.18.129 8080
Serving HTTP on 192.168.18.129 port 8080 (http://192.168.18.129:8080/)

# 默认启动一个server
[root@localhost ~]# python3.14 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
端口号理解

端口号本质上是操作系统分配给网络进程的唯一标识。当数据包通过IP地址到达你的电脑后,操作系统需要根据“端口号”来决定把数据交给哪个应用程序。

  • 如果端口上有程序在监听(处于 LISTENING 状态),操作系统就会把数据复制给该进程。
  • 如果端口上没有程序监听,操作系统会认为没有应用需要这份数据,直接丢弃数据包,并向发送方回复一个 ICMP(互联网控制报文协议)不可达 或 RST(重置连接) 报文,表示“连接被拒绝”。

如果一个端口已经被进程 A 监听,那么进程 B 再想监听同一个端口(特别是 TCP)会报错 “Address already in use”。这保证了端口与进程的一一对应关系,也印证了“端口必须有程序监听”这一规则。

==–bind 0.0.0.0 就是你说的”通配符无论哪张网卡都会处理”,任何 IP 访问这个端口都能响应。==

最简方式:http.server 模块

1. 基本启动

bash

# 默认端口 8000,绑定所有网卡
python3 -m http.server

# 指定端口
python3 -m http.server 8080

# 指定绑定地址(0.0.0.0 表示所有网卡)
python3 -m http.server 8080 --bind 0.0.0.0

--bind 0.0.0.0 就是你说的”通配符无论哪张网卡都会处理”,任何 IP 访问这个端口都能响应。

2. 指定目录

bash

# 把 /var/www/html 作为根目录
python3 -m http.server 8080 --bind 0.0.0.0 --directory /var/www/html

3. 浏览器访问

text

http://192.168.1.100:8080/
http://127.0.0.1:8080/
http://localhost:8080/

五、技术选型的取舍(Nginx 大而全 vs Python 小而轻)

  • Nginx 多进程:在高并发场景下利用多核,进程数量多,资源占用高,配置复杂,适合生产级基础设施。
  • Python http.server / 自写代理:单进程/单线程,性能有限,但极轻量。当业务简单(如内部调试、单点中转)且不希望被复杂的 Nginx 配置和进程管理干扰时,Python 直写是快速验证思想的最佳方案。
  • 核心:脱离场景谈技术没有意义。复杂业务用 Nginx,快速验证或轻量级定制用 Python,这是工程取舍的智慧。

tcp还有重传,流量控制,滑动窗口,拥塞控制等机制,理论巨多,大家可以自行拓展,看看计算机网络相关数据

常用端口号

22(SSH)、80/443(HTTP/HTTPS)、3306(MySQL)、6379(Redis)、53(DNS)

网络相关命令

### ss(替代 netstat)
# -a, --all           display all sockets
# -l, --listening     display listening sockets
# -t, --tcp           display only TCP sockets
# -u, --udp           display only UDP sockets
# -p, --processes     show process using socket
ss -tlnp      # TCP 监听端口 + 进程名
ss -tulnp     # TCP+UDP 监听

[root@localhost ~]# ss -tlnp
State            Recv-Q           Send-Q                     Local Address:Port                     Peer Address:Port           Process
LISTEN           0                128                              0.0.0.0:22                            0.0.0.0:*               users:(("sshd",pid=927,fd=3))
LISTEN           0                128                                 [::]:22                               [::]:*               users:(("sshd",pid=927,fd=4))

# 统计摘要
[root@localhost ~]# ss -s
Total: 131
TCP:   8 (estab 6, closed 0, orphaned 0, timewait 0)

Transport Total     IP        IPv6
RAW       2         0         2
UDP       4         3         1
TCP       8         7         1
INET      14        10        4
FRAG      0         0         0

# lsof
# -i select IPv[46] files, 读取ip相关的运行时文件
lsof -i :8080       # 谁在用 8080
lsof -i tcp:3306    # MySQL 谁在监听