1. 学习目的
实现 不同主机之间的进程间通信。
在 Linux 下,进程间通信(IPC)不仅可以发生在同一台主机上,也可以通过网络实现不同主机之间的通信。要做到这一点,必须同时满足以下两个条件:
-
物理层面:不同主机之间必须通过物理网络互联互通(如网线、交换机、路由器等)。
-
软件层面:进程之间必须通过网络协议进行通信。
2. 基础概念
-
IP 地址
计算机的"软件地址",用来标识计算机设备
-
MAC 地址
计算机网卡的"硬件地址",唯一且固定。
-
端口号
用来区分同一主机上的不同进程,保证多个网络服务可以同时运行。
3. 网络协议
网络通信需要遵循统一的标准,即 网络协议。
3.1 OSI 七层模型(理论模型)
OSI(Open System Interconnect)是一个通信标准框架,分为 7 层:
-
应用层:提供应用服务(如文件传输、电子邮件)。
-
表示层:数据加密/解密,压缩/解压缩。
-
会话层:建立数据传输通道, ---》会话
-
传输层:提供端到端的传输服务(传输的方式 UDP TCP 端口号)。
-
网络层:实现数据路由,路径规划 路由器 ip。
-
数据链路层:封装成帧,点对点通信(局域网内通信),差错检测 交换机 ARP。
-
物理层:定义物理介质(网线、光纤),传输比特流(0/1)。
3.2 TCP/IP 模型(应用模型)
相比 OSI 七层,TCP/IP 模型更贴近实际应用。
五层模型
-
应用层:
-
HTTP:超文本传输协议
-
HTTPS:加密的 HTTP(SSL加密算法)
-
FTP:文件传输协议(TCP)
-
TFTP:简单文件传输协议(UDP)
-
MQTT:物联网协议
-
DNS:域名解析服务
-
-
传输层:
-
TCP(传输控制协议,可靠,面向连接)
-
UDP(用户数据报协议,不可靠,面向无连接)
-
-
网络层:
- IP 协议(IPv4 / IPv6)
-
数据链路层:
- ARP(地址解析协议)
-
物理层
四层模型
-
应用层
-
传输层
-
网络层
-
网络接口层
4. IP 协议
-
IPv4:32 位地址
-
IPv6:128 位地址
4.1 表示方式
-
点分十进制:
192.168.1.140 (用户表示形式) 点分十进制
-
二进制存储:
11000000 10101000 00000000 10001100 (计算机存储形式) 32bits
4.2 IP 地址组成
IP地址 = 网络位 + 主机位
例:192.168.0.121/24
-
/24
:网络位长度 24 位 -
网络位:表示属于哪个网段
-
主机位:表示网段中(局域网)的哪一台主机
4.3 子网掩码
例:255.255.255.0
-
11111111.11111111.11111111.00000000
用来区分IP地址的网络位和主机位,搭配IP地址使用。
子网掩码是1的部分对应IP地址的网络位
子网掩码是0的部分对应IP地址的主机位
4.4 特殊地址
IP地址网络位不变,主机位全为0,则为该IP地址的网段号
192.168.1.3
255.255.0.0
192.168.0.0
位于
192.168.1.0 网段内(网段内的IP能直接通信)
192.168.1.255
IP地址网络位不变,主机位全为1,则为该IP地址的广播号
192.168.1.3
255.255.255.0
广播号:
192.168.1.255(向广播号发送信息,所有局域网内IP都能收到此信息)
-
网段号:主机位全为 0
-
广播号:主机位全为 1,局域网内所有主机都能收到
-
网关地址 :通常为
xxx.xxx.xxx.1
,用于不同网段间通信
4.5 IP 地址分类
-
A 类地址
-
范围:1.0.0.0 - 126.255.255.255
子网掩码:255.0.0.0 126*2^24
用于管理大规模网络
私有IP地址:10.0.0.0 - 10.255.255.255
127.0.0.0 回环地址
-
-
B 类地址
-
范围:128.0.0.0 - 191.255.255.255
子网掩码:255.255.0.0 2^16
管理大中规模网络
私有IP地址:172.16.0.0 - 172.31.255.255
-
-
C 类地址
-
范围:192.0.0.0 - 223.255.255.255
子网掩码:255.255.255.0 2^8
管理中小规模网络
私有IP地址:192.168.0.0 - 192.168.255.255
-
-
D 类地址
-
224.0.0.0 - 239.255.255.255
组播和广播使用
-
-
E 类地址
-
240.0.0.0 - 255.255.255.254
用来进行实验
-
公有IP:由电信公司直接分配,并需要付费的IP地址, 可以直接访问internet
私有IP:不能直接访问internet的ip地址
节省ip地址
5. 网络端口号
-
端口号:16 位无符号整数(0 - 65535)
-
功能:区分同一主机上的不同网络进程
分类
-
系统端口(0-1023)
-
HTTP:80
-
FTP:20/21
-
TFTP:69
-
HTTPS:443
-
-
注册端口(1024-49151)
- MQTT:1883 / 8883
-
动态端口(49152-65535)
- 私有、临时使用

6. Linux 网络配置
常用命令
-
ping ip/域名
测试与目标主机是否连通
ping www.baidu.com
-
ifconfig
(Linux)查看当前主机 IP 地址
ipconfig
(Windows)查看 Windows 主机 IP 地址
虚拟机配置
-
虚拟机 → 设置 → 网络适配器 → 桥接模式
-
编辑 → 虚拟网络编辑器 → VMnet0 → 桥接至当前 PC 网卡
-
修改网络配置文件(示例)
sudo vim /etc/network/interfaces
auto lo
iface lo inet loopback
auto ens33
iface ens33 inet dhcp
-
重启网络服务
sudo /etc/init.d/networking restart
-
测试
ping www.baidu.com
7. UDP 协议与编程
-
UDP(User Datagram Protocol)属于传输层协议。
-
用户数据报协议(User Datagram Protocol)
-
特点:无连接、不可靠、效率高,适合实时性强的应用(如视频、语音)。
7.1 网络编程模型
-
B/S 模型(Browser / Server)
-
客户端通用(浏览器)
-
一般只开发服务器端
-
客户端的数据均来自服务器
-
-
C/S 模型(Client / Server)
-
专用客户端
-
服务器和客户端都需开发
-
客户端可保存部分资源,本地加载
-
7.2 UDP 编程流程
基本概念
- 套接字(socket):一个文件描述符,应用层与网络通信的接口。
编程步骤

-
客户端:
-
创建 socket
-
填写服务器地址结构
-
发送数据
sendto
-
接收数据
recvfrom
-
关闭 socket
-
-
服务器:
-
创建 socket
-
绑定端口
bind
-
循环接收数据
recvfrom
-
可选择回应客户端
sendto
-
关闭 socket
-
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
功能:创建通信的套接字
参数:
domain:网络层使用什么协议族
AF_INET:IPv4
AF_INET6:IPv6
type:规定传输层的协议
SOCK_DGRAM : UDP协议
SOCK_STREAM:TCP协议
SOCK_RAW :原始套接字
protocol :0 按照默认协议方式创建
返回值:
成功:套接字
失败:-1
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
功能:向网络套接字发送数据
参数:
sockfd:套接字
buf: 要发送的数据的首地址
len:要发送的字节数
flags: 0:按照默认方式发送
dest_addr:接收方的地址信息(IP+端口号)
addrlen:接收方地址的大小
返回值:
成功:实际发送的字节数
失败:-1
man 7 ip
struct sockaddr_in {
sa_family_t sin_family; /* address family: AF_INET */
in_port_t sin_port; /* port in network byte order */
struct in_addr sin_addr; /* internet address */
};
/* Internet address. */
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};
网络字节序:大端 network
主机字节序:小端 50000 host
0x1234
小端:0x34
0x12
大端:
0x12
0x34
uint32_t htonl(uint32_t hostlong); 主机转网络
uint16_t htons(uint16_t hostshort); 主机转网络
uint32_t ntohl(uint32_t netlong); 网络转主机
uint16_t ntohs(uint16_t netshort); 网络转主机
in_addr_t inet_addr(const char *cp);
功能:
将字符串IP地址转换成二进制IP地址形式
char *inet_ntoa(struct in_addr in);
功能:
将二进制ip转换成字符串
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
功能:绑定自己的IP地址和端口号
参数:
sockfd:套接字
addr:需要绑定的地址
addrlen:地址大小
返回值:
成功:0
失败:-1
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
功能:从套接字上接收数据
参数:
sockfd:套接字
buf:存放接收数据的内存首地址
len:希望接收的字节数
flags:0 :按照默认方式接收(阻塞)
src_addr:发送方的地址信息
addrlen:发送发地址的指针
功能:
成功:实际接收到的字节数
失败:-1