一、网络通信模型:OSI 与 TCP/IP
不同主机间的进程通信,依赖标准化的网络模型实现数据传输。目前主流模型分为 “理想型” OSI 七层模型和 “实用型” TCP/IP 四层模型。
1. OSI 七层模型(开放系统互联模型)
为统一网络通信逻辑设计的理想模型,尚未完全落地,但定义了通信的分层职责:
- 应用层:为用户提供具体服务,如文件传输(TFTP)、电子邮件、网页访问,对应程序如
a.out
可调用该层接口; - 表示层:统一数据格式,处理加密(如 HTTPS 加密)、压缩(如 gzip),确保不同主机能解析数据;
- 会话层:管理进程通信会话,维护连接状态(如
keep-alive
保活、keep-close
断开),处理网络中断后的会话恢复; - 传输层:负责端到端数据传输,提供两种核心协议 ——TCP(可靠传输,适合文件)和 UDP(实时性好,适合直播、音频);
- 网络层:解决 “如何找到目标主机”,通过 IP 地址路由选择、NAT 地址转换,实现跨网段通信;
- 数据链路层:处理物理相邻主机的传输,将数据封装为 “帧”,做 CRC 校验(差错控制),分 LLC(逻辑链路控制)和 MAC(介质访问控制)子层,依赖交换机转发;
- 物理层:将数据转为电信号 / 光信号,通过介质(双绞线 100Mb/s、光纤 Gb 级、同轴电缆 10Gb/s、无线 2.4G/5G)传输,定义设备的机械和电气特性(如网线接口)。
2. TCP/IP 四层模型(网际互联模型)
工业标准模型,是互联网的核心协议栈,将 OSI 七层简化为四层,更贴合实际应用:
- 应用层:整合 OSI 应用层、表示层、会话层功能,包含 HTTP(网页)、TFTP(短距离文件传输)、FTP(文件传输)、DNS(域名解析)、SNMP(网络监管)等协议,如
www.taobao.com
通过 DNS 解析为 IP 地址; - 传输层:对应 OSI 传输层,用 TCP(可靠)、UDP(实时)协议,通过 “端口号” 区分主机上的应用程序(如 HTTP 用 80 端口、SSH 用 22 端口);
- 网络层:对应 OSI 网络层,核心是 IP 协议,配合 ICMP(网络诊断,如 ping)、RIP/OSPF(路由协议),负责跨网段路由;
- 接口层:整合 OSI 数据链路层、物理层,包含 ARP(通过 IP 查 MAC 地址)、RARP(通过 MAC 查 IP),依赖网卡驱动实现硬件交互(如 1GB 网卡)。
二、核心传输层协议:UDP 与 TCP
传输层是端到端通信的关键,UDP 和 TCP 分别对应 “实时性” 和 “可靠性” 需求,均基于 C/S(客户端 / 服务器)模式。
1. UDP(用户数据报协议)
特性
- 无连接:通信前无需建立连接,无需维护网络状态,开销小;但无法感知对方进程是否关闭,需手动发消息通知;
- 不可靠传输:数据可能丢包,但省略重传等机制,实时性极强,适合直播、视频、音频等对延迟敏感的场景;
- 多播 / 广播支持:天然支持一对多通信,可向组播地址(如 239.255.255.254)发送数据,仅加入组播组的设备接收;
- 数据有边界:发送和接收次数对应,不会像 TCP 那样合并数据。
C/S 模式流程与核心函数
- 服务端:
socket()
→bind()
→recvfrom()
→close()
socket(PF_INET, SOCK_DGRAM, 0)
:创建 UDP 套接字,SOCK_DGRAM
指定 UDP 类型;bind()
:必选,绑定 IP 和端口,确保客户端能找到服务端;recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen)
:接收数据,src_addr
可选,用于获取客户端地址,flags=0
表示阻塞接收。
- 客户端:
socket()
→(可选bind()
)→sendto()
→close()
bind()
可选,客户端可由系统自动分配端口;sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen)
:发送数据,dest_addr
必选,指定服务端地址,返回成功发送的字节数,失败返回 - 1。
2. TCP(传输控制协议)
特性
- 有连接:通信前需通过 “三次握手” 建立连接,连接过程中实时维护状态,一方断开时另一方可感知;
- 可靠传输:通过 “应答 + 超时重传” 机制确保数据不丢包、不重复,适合文件下载、网页访问等对可靠性要求高的场景;
- 流式套接字:数据无边界,发送和接收次数无需对应(如发送 2 次 100 字节,可能一次接收 200 字节);
- 拥塞控制:自动调整发送速率,避免网络拥塞,但延迟高于 UDP。
C/S 模式流程与核心函数
- 服务端:
socket()
→bind()
→listen()
→accept()
→recv()
→close()
socket(PF_INET, SOCK_STREAM, 0)
:创建 TCP 套接字,SOCK_STREAM
指定 TCP 类型;listen(int sockfd, int backlog)
:监听连接,backlog
指定等待队列最大长度;accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
:从等待队列取出连接,返回 “通信套接字”(后续通信用此套接字,原sockfd
继续监听),addr
可获取客户端地址;recv(int sockfd, void *buf, size_t len, int flags)
:接收数据,sockfd
为accept()
返回的通信套接字,flags=0
阻塞接收。
- 客户端:
socket()
→connect()
→send()
→close()
connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
:必选,向服务端发起连接请求,成功返回 0,失败返回 - 1;send(int sockfd, const void *buf, size_t len, int flags)
:发送数据,返回成功发送字节数,失败返回 - 1。
- 关键配置:
setsockopt(listfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))
:允许端口复用,避免服务端重启时因 “端口占用” 报错。
三、IP 地址:网络通信的 “地址标识”
IP 地址(IPv4)是 32 位二进制数,用 “点分十进制” 表示(如 192.168.1.1),分为 “网络位”(确定网段)和 “主机位”(区分网段内设备),按网络位长度分为 A-E 五类,核心用途是定位主机。
1. 五类 IP 地址核心参数
类别 | 地址范围 | 网络位 / 主机位 | 默认子网掩码 | 用途 | 私有地址范围 |
---|---|---|---|---|---|
A 类 | 1.0.0.0-126.255.255.255 | 8 位 / 24 位 | 255.0.0.0 | 超大规模网络(如运营商) | 10.0.0.0-10.255.255.255 |
B 类 | 128.0.0.0-191.255.255.255 | 16 位 / 16 位 | 255.255.0.0 | 中大规模网络(如校园网) | 172.16.0.0-172.31.255.255 |
C 类 | 192.0.0.0-223.255.255.255 | 24 位 / 8 位 | 255.255.255.0 | 中小网络(如家庭 / 企业内网) | 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.255 | 无 | 无 | 科研实验 | 无 |
2. 特殊 IP 地址
- 环回地址:127.0.0.1,用于设备自身通信(如测试本机服务),数据不经过物理网卡;
- 广播地址:网段内主机位全为 1 的地址(如 192.168.0.255),向该地址发送数据,网段内所有设备接收;
- 网关地址:网段的 “出口”(如 192.168.0.1),跨网段通信需通过网关(如路由器)转发。
四、网络配置与 Socket 基础
1. 单机上网核心配置
要实现单机上网,需满足 3 个条件:有网络接口(如网卡)、正确的 IP 地址、网关与 DNS 配置:
- 设置 IP:
ifconfig ethX X.X.X.X/24 up
(如ifconfig ens33 192.168.0.13/24 up
),/24
表示子网掩码 255.255.255.0; - 配置网关:
route add default gw X.X.X.X
(如route add default gw 192.168.0.1
),网关为路由器地址; - 配置 DNS:编辑
/etc/resolv.conf
,添加nameserver 8.8.8.8
(谷歌 DNS)或114.114.114.114
(国内 DNS),用于解析域名; - 测试网络:
ping www.baidu.com
,能收到回复表示网络通畅;netstat -anp
查看当前网络连接状态。
2. Socket:网络通信的 “桥梁”
Socket(套接字)是用户程序与内核网络协议栈的接口,类似 “文件句柄”—— 无 Socket,程序无法调用 TCP/IP 协议。核心概念:
- 标识方式:
IP+端口号
,IP 定位主机,端口号(1-65535)定位主机上的应用,1000 以内为系统知名端口(如 HTTP 80、MySQL 3306); - 地址结构体:
- 通用结构体
struct sockaddr
:用于函数参数占位,包含sa_family
(地址族,如 AF_INET 表示 IPv4)和sa_data
(地址信息); - IPv4 专用结构体
struct sockaddr_in
:包含sin_family
(AF_INET)、sin_port
(端口号,需转网络字节序)、sin_addr
(IP 地址,sin_addr.s_addr
存 32 位二进制 IP)、sin_zero[8]
(占位,填 0);
- 通用结构体
- 字节序转换:网络字节序为 “大端”(高位字节存低地址),主机字节序可能为小端,需用函数转换:
- 主机→网络:
htonl(uint32_t hostlong)
(32 位 IP)、htons(uint16_t hostshort)
(16 位端口); - 网络→主机:
ntohl(uint32_t netlong)
、ntohs(uint16_t netshort)
。
- 主机→网络:
五、TCP 连接管理:三次握手与四次挥手
TCP 通过 “三次握手” 建立可靠连接,“四次挥手” 释放连接,确保通信有序。
1. 三次握手(建立连接)
目标:确认双方收发能力,同步初始序列号(Seq),流程如下:
- 客户端→服务端:发送
SYN
报文(Seq=x,x 为客户端随机初始序列号),客户端进入SYN_SENT
状态; - 服务端→客户端:回复
SYN+ACK
报文(Seq=y,y 为服务端初始序列号;Ack=x+1,确认收到客户端 SYN),服务端进入SYN_RCVD
状态; - 客户端→服务端:发送
ACK
报文(Seq=x+1;Ack=y+1,确认收到服务端 SYN),双方均进入ESTABLISHED
状态,连接建立,开始传输数据。
2. 四次挥手(释放连接)
目标:确保双方数据传输完成后释放资源,流程如下(以客户端主动关闭为例):
- 客户端→服务端:发送
FIN+ACK
报文(Seq=k,k 为客户端已发数据最后序号;Ack=m,确认服务端数据),客户端进入FIN_WAIT_1
状态,表明 “客户端无数据可发”; - 服务端→客户端:回复
ACK
报文(Seq=m;Ack=k+1),服务端进入CLOSE_WAIT
状态,客户端进入FIN_WAIT_2
状态,此时服务端仍可发数据; - 服务端→客户端:服务端无数据可发时,发送
FIN+ACK
报文(Seq=n,n 为服务端已发数据最后序号;Ack=k+1),服务端进入LAST_ACK
状态; - 客户端→服务端:发送
ACK
报文(Seq=k+1;Ack=n+1),客户端进入TIME_WAIT
状态(等待 2MSL 确保服务端收到 ACK),服务端收到后进入CLOSED
状态;客户端等待后也进入CLOSED
状态,连接彻底释放。