网络基础与协议栈:TCP/IP协议栈回顾、UDP与TCP的选择、端口与地址规划、MTU与分片问题

做物联网设备入网,说白了就是让设备能跟服务器对上话。但对话之前,你得先搞清楚它们之间用什么语言、走哪条路。这就是我们今天要聊的——网络基础与协议栈。

我见过太多工程师,一上来就调应用层代码,结果设备死活连不上。最后发现,是底层协议选错了,或者MTU没配好。嗯,基础不牢,地动山摇。咱们先把地基打扎实。

TCP/IP协议栈回顾

TCP/IP协议栈,其实就是一套分层的通信规则。从下往上,一共四层:

  • 网络接口层:负责物理传输,比如以太网、Wi-Fi。说白了就是管“怎么把比特流发出去”。
  • 网络层:核心是IP协议,负责寻址和路由。它决定“数据包该往哪个方向走”。
  • 传输层:TCP和UDP就在这层。它解决“数据怎么可靠/快速地交给对方”。
  • 应用层:HTTP、MQTT、CoAP这些协议都在这里。它定义“数据长什么样、怎么解析”。

每一层只关心自己的事,下层为上层服务。这种分层设计,让问题隔离变得简单。我在项目中排查过一个问题:设备上报数据偶尔丢失。查了半天,发现是应用层MQTT的QoS设置没问题,但底层的TCP窗口太小,导致数据被丢弃。你看,不懂分层,你连问题出在哪都找不到。

核心原则:排查网络问题时,从底层往上层逐层检查。先看物理层通不通,再看IP层能不能路由,最后看传输层和应用层。

TCP/IP 协议栈四层模型 应用层 (HTTP, MQTT, CoAP, DNS) 传输层 (TCP, UDP) 网络层 (IP, ICMP, ARP) 网络接口层 (以太网, Wi-Fi, PPP) 数据封装:每层添加头部,下层为上层提供服务

UDP与TCP的选择

这是物联网设备入网时最纠结的问题之一。TCP可靠,但开销大;UDP快,但会丢包。怎么选?

我个人习惯先看业务场景:

  • TCP:适合需要可靠传输的场景,比如固件升级、配置下发、传感器数据上报(不能丢)。TCP有重传机制、流量控制、拥塞控制,但三次握手和四次挥手会增加延迟。
  • UDP:适合实时性要求高、可以容忍少量丢包的场景,比如视频流、音频流、实时控制指令。UDP无连接,开销小,但应用层需要自己处理丢包和乱序。

你想想看,一个温度传感器,每5秒上报一次数据。丢一个包,下次上报就补回来了。用TCP反而浪费带宽。但如果是门锁的开锁指令,丢包就意味着门打不开——这时候必须用TCP。

我的经验:在物联网设备中,我常用UDP + 应用层ACK的方案。既保留了UDP的低延迟,又通过应用层确认保证关键指令的可靠性。说白了,就是自己造一个轻量级的可靠传输。

特性 TCP UDP
连接方式 面向连接(三次握手) 无连接
可靠性 可靠(重传、确认) 不可靠(尽力而为)
延迟 较高(握手、拥塞控制) 低(无握手)
头部开销 20字节 8字节
适用场景 固件升级、配置下发、关键指令 视频流、传感器广播、实时控制

避坑指南:我曾经在一个项目中,用UDP传输固件包。结果因为网络丢包率高,设备反复请求重传,导致升级时间从5分钟变成了2小时。后来改成TCP,虽然慢一点,但至少能稳定完成。记住:大文件传输,别用UDP裸奔。

端口与地址规划

端口和地址,是设备入网的门牌号。搞错了,设备就找不到家。

IP地址规划:物联网设备通常使用私有IP地址(如192.168.x.x或10.x.x.x)。但要注意,如果设备需要跨公网通信,必须配合NAT或端口映射。我个人习惯给设备分配静态IP,避免DHCP租约到期导致地址变化。

端口规划:每个应用服务使用一个端口。常见端口:

  • MQTT:1883(TCP),8883(TLS)
  • CoAP:5683(UDP),5684(DTLS)
  • HTTP:80(TCP),443(TLS)
  • 自定义服务:建议使用1024以上的端口,避免与系统端口冲突

我在项目中遇到过一个问题:设备上报数据时,服务器收不到。查了半天,发现设备使用的端口被防火墙拦截了。嗯,端口规划时,一定要跟网络管理员确认防火墙策略。

最佳实践:为每个设备类型分配独立的端口段。比如温度传感器用5000-5100,门锁用5200-5300。这样排查问题时,一看端口就知道是哪种设备。

MTU与分片问题

MTU(最大传输单元)是网络接口层能传输的最大数据包大小。以太网标准MTU是1500字节。如果IP层的数据包超过MTU,就需要分片。

分片会带来什么问题?

  • 性能下降:分片和重组消耗CPU资源。
  • 丢包放大:一个分片丢失,整个数据包都要重传。
  • 安全风险:分片攻击(如Teardrop攻击)利用分片漏洞。

物联网设备通常资源受限,CPU和内存都不强。分片对它们来说,是个不小的负担。

我建议的做法:

  1. 控制应用层数据大小:让每个TCP或UDP报文尽量小于MTU。比如以太网环境下,应用层数据控制在1460字节以内(1500 - 20字节IP头 - 20字节TCP头)。
  2. 开启Path MTU Discovery:让系统自动探测路径上的最小MTU,避免分片。
  3. 避免UDP大包:UDP没有TCP的流控,容易产生大包导致分片。如果必须用UDP传输大数据,应用层自己做分片和重组。

我的经验:在低功耗广域网(如LoRa、NB-IoT)中,MTU通常很小(几百字节)。我习惯把应用层数据包控制在128字节以内,既避免分片,也减少重传开销。记住:小包更安全。

网络类型 典型MTU 建议应用层数据大小
以太网 1500 ≤ 1460
Wi-Fi 1500 ≤ 1460
4G/5G 1500 ≤ 1400(考虑隧道开销)
LoRa 250-500 ≤ 128
NB-IoT 1358 ≤ 1200

避坑指南:我曾经在一个项目中,设备通过4G模块上报图片。图片压缩后约10KB,直接塞进UDP包。结果因为MTU分片,网络稍微波动就丢包,图片永远传不完。后来改成TCP + 应用层分片(每片1KB),问题解决。记住:大文件传输,一定要考虑MTU。