网络基础与TCP/IP协议栈

说实话,每次带新人做网络编程,我第一件事就是让他们先把网络模型搞清楚。为什么?因为你不懂数据怎么封装、怎么解封装,后面写socket代码就是瞎蒙。我自己刚入行那会儿,也踩过这个坑——代码能跑,但出了问题完全不知道怎么排查。

今天咱们就把这块地基打牢。你想想看,网络通信就像寄快递,你得知道包裹怎么打包、怎么拆包、地址怎么写。网络模型就是这套规则。

OSI七层模型:理论上的完美蓝图

OSI七层模型是国际标准化组织(ISO)搞出来的。说实话,它太完美了,完美到实际没人完全照着它实现。但作为理论基础,你必须懂。

层级 名称 核心功能 典型协议/设备
7 应用层 为用户提供网络服务接口 HTTP、FTP、SMTP
6 表示层 数据格式转换、加密、压缩 SSL/TLS、JPEG
5 会话层 建立、管理、终止会话 NetBIOS、RPC
4 传输层 端到端可靠传输 TCP、UDP
3 网络层 路由选择、逻辑寻址 IP、ICMP、路由器
2 数据链路层 帧封装、MAC寻址、差错检测 以太网、交换机
1 物理层 比特流传输、电气特性 网线、集线器、光纤

我的经验:面试时经常有人把七层背得滚瓜烂熟,但一问「HTTP在哪一层」就卡壳。记住:应用层是离用户最近的,物理层是离网线最近的。中间层一层层往上叠。

TCP/IP四层模型:实战中的王者

OSI七层太啰嗦了,实际互联网用的是TCP/IP四层模型。它把上面三层(应用层、表示层、会话层)合并成一层,就叫应用层。下面两层(物理层、数据链路层)也合并成一层,叫网络接口层。

说白了,TCP/IP模型就是OSI的简化版,更实用。我写网络程序这么多年,99%的时间只跟四层打交道。

TCP/IP四层 对应OSI层 核心协议
应用层 5/6/7 HTTP、DNS、FTP
传输层 4 TCP、UDP
网络层 3 IP、ICMP
网络接口层 1/2 以太网、ARP

小提示:写C语言网络程序时,你主要操作的是传输层(socket)和应用层(协议解析)。网络层和网络接口层由操作系统内核帮你搞定了。

数据封装与解封装:包裹的旅行

数据从应用层一路往下走,每经过一层就加一个头部。这叫封装。到了接收端,从下往上走,每层拆一个头部。这叫解封装。

我举个例子。你发一条HTTP请求「GET /index.html」。这个过程是这样的:

  1. 应用层:生成HTTP请求报文
  2. 传输层:加上TCP头部(源端口、目的端口、序列号等),变成TCP段
  3. 网络层:加上IP头部(源IP、目的IP),变成IP包
  4. 网络接口层:加上MAC头部(源MAC、目的MAC),变成以太网帧
  5. 物理层:变成比特流,通过网线发出去

接收端反过来,一层层拆掉头部,最后拿到HTTP报文。

注意:我曾经遇到过一个bug,客户端发数据正常,服务端收不到。查了半天,发现是MTU(最大传输单元)设置问题,IP层把数据分片了,服务端重组失败。嗯,这就是封装过程中容易踩的坑。

IP地址与端口号:网络世界的坐标

IP地址定位一台主机,端口号定位主机上的一个进程。两者缺一不可。

IP地址:IPv4是32位,通常写成点分十进制,比如192.168.1.1。IPv6是128位,写成冒号十六进制。目前主流还是IPv4,但IPv6在慢慢普及。

端口号:16位整数,范围0-65535。其中:

  • 0-1023:知名端口,需要root权限才能用。比如HTTP是80,HTTPS是443
  • 1024-49151:注册端口,给应用程序用
  • 49152-65535:动态/私有端口,客户端临时使用

我的习惯:写服务端程序时,我一般用5000以上的端口,避免跟系统服务冲突。客户端端口由操作系统随机分配,你不用操心。

核心知识体系一览

下面这张图,把今天讲的核心逻辑串起来了。你仔细看看,数据是怎么从应用层一路封装到物理层的。

数据封装与解封装过程 发送端(封装) 应用层 HTTP请求报文 传输层 TCP头部 + 数据 网络层 IP头部 + TCP头部 + 数据 网络接口层 MAC头部 + IP头部 + TCP头部 + 数据 物理传输介质 网线 / 光纤 / 无线 接收端(解封装) 网络接口层 拆MAC头部 网络层 拆IP头部 传输层 拆TCP头部 应用层 HTTP请求报文

写在最后

网络模型这东西,你光背没用。我建议你打开Wireshark抓个包看看,亲眼看到TCP头部、IP头部长什么样,比看十遍书都管用。

下一章咱们就开始写真正的C语言socket代码了。到时候你会发现,理解了今天这些基础,写代码就是水到渠成的事。


公众号:蓝海资料掘金营,微信deep3321