tntxxd 发表于 2025-3-16 18:12:28

为了让51单片机联网,自己设计了一个轻量的网络协议栈

一直想让单片机(尤其是51)联网,感觉这样很好玩。但是没有非常轻量的ip实现,而且本人不太想让单片机用ip网络(占地址)。于是设计了非常轻量的网络协议栈,称为zxdnet(简称znet)。他可以工作对mtu的最小要求是48字节,所以可以在很多链路上,例如串口和红外。他很适合爱好者用来玩,也可以用于学习网络原理。znet适用于构建完全私有的组织内网络而不是公共网络。
报文中所有字段都是大端序的。

znet和ip一样是采用分层架构的分组交换网络,数据包可以经过多个路由器转发后到达目的地。
首先介绍下znet的网络层协议zp的报头:
(参见图1)

介绍下各字段:
BF(2bit):基本标志。前1bit表示目标地址类型,如果是0目标地址为普通地址,如果是1目标地址为组播地址(目前还没设计组播)。后1bit表示无错误标志,如果此位为1,在发生错误的时候就不会通过zcp协议回报错误(类似ip中的icmp错误回报)

Proto(4bit):上层协议号
      0: ZARP (ZXDNET 地址解析协议)
      1: ZCP (ZXDNET 控制协议)
      2: TUDP (简单用户数据报协议)
      3: UDP (用户数据报协议)
      4: TCP (传输控制协议)
      5: IPoZP (IP over ZP)
      6: RAW
      7-15: 用户自定义

Time To Live(8bit):TTL
      这个字段定义了数据报允许的最大跳数。发送方初始化这个值,每个路由节点在处理时将其减一。如果TTL在数据报到达目的地之前变为零,数据报会立即被丢弃。这个机制防止了无限路由循环。

Extra Flag(16bit):额外标志。用户自定义,一般用于qos。

Total Length (16bit):报文总长度(字节),包括网络层头(16字节)及其数据。

Header Checksum(16bit):首部校验和。
   仅对头部字段计算校验和。由于某些头部字段(例如生存时间)在传输过程中可能会改变,因此每个处理头部的节点都必须验证和重新计算这个校验和。
    校验和字段是头部中所有16位字的反码和的16位反码。在计算过程中,校验和字段本身被视为零。如果计算出的校验和为零,则以全1的形式传输。如果校验和字段本身为0,就跳过校验,这适用于可靠链路。

Source Address和Destination Address:源地址和目标地址。

地址分配:
   Zxdnet使用32位地址空间,采用CIDR,分类如下:

   未指定/本地广播地址(0.0.0.0/32):
   位模式:00000000 00000000 00000000 00000000。
   作为源:未初始化设备(例如,启动时的0.0.0.0)。
   作为目的地:有限广播(在子网之外不可路由)。

   回环地址(0.0.0.128/25):
   位模式:00000000 00000000 00000000 1XXXXXXX。
   仅限于内部主机通信。

   NAT扩展地址(0.0.0.64/26):
   位模式:00000000 00000000 00000000 01XXXXXX。
   仅限于本地地址扩展。
   NAT处理:典型的NAT中间盒有两个接口,一个连接到包含最多63个NAT设备的局域网(接口地址为0.0.0.64/26),另一个连接到全球网络(具有全局单播地址)。对于使用端口号的传输层协议,NAT设备将全局单播地址的端口号划分为几个段,每个段包含相同数量的端口。这些端口然后映射到每个设备的前几个端口号(从0开始)。中间盒本身将被分配第一个端口段。例如,对于一个总共有256个端口的传输层协议,NAT设备将这些端口划分为64个段,每个段包含4个端口。端口0-3由中间盒使用,端口4-7映射到第一个NAT设备的端口0-3,依此类推,端口252-255映射到第63个NAT设备的端口0-3。对于ZCP Echo和ZCP错误报告,中间盒充当代理。ZARP和IPoZP不支持NAT穿越。NAT嵌套不被支持。

   保留地址(0.0.0.1-0.0.0.63):
   位模式:00000000 00000000 00000000 00XXXXXX(XXXXXX!=000000)。
   这些地址不得分配给任何设备或用于数据报头。

   单播地址(所有非保留地址):
   分配给设备,全局可路由。
znet地址空间中只有256个为特殊用途,其他全部可以分配给设备。znet没有所谓“网络地址“,表示一个网络可以用第一个设备地址+子网前缀长度。znet也没有所谓”局域网广播地址“,只有一个不可跨网关的有限广播地址0.0.0.0。这样的设计十分简化,可以高效实现,节省地址。

zp协议不支持网络层分片,因为违反了网络层无连接原则,并且一些运输层不需要,占用了头部空间。

下面介绍一些运输层协议(上面提到的)。

首先是zarp协议。他设计的很简洁。如果链路层目标地址是广播地址就是请求,是设备地址就是响应。

zcp协议用于控制和诊断网络本身。校验和算法与zp头的一致,但是涵盖zcp头和他的数据。zcp报文最大48字节(包括zp头)。zcp目前有2个作用:错误回报和回显。首先说下错误回报报文。
(参见图2)

以下是errcode定义:

0 = 网络不可达。

1 = 主机不可达。

2 = 协议不可达。

3 = 端口不可达。

4 = 超出MTU。

5 = 生存时间在传输中超出。

6 = 数据丢失。

7 = 数据损坏。

8 = 链路拥塞。

9 = 显式拥塞通告。

10 = 不支持组播。

注意,如果是超出MTU,原始zp头里的校验和字段会被替换为mtu。


然后介绍下回显报文。
(参见图3)


code=0就是回显请求,code=1就是回显响应。对方收到后改变code,重新计算校验和,然后发回报文, Identifier ,Sequence Number和Data不能改变。
data是用户数据,最大22字节。
znet支持跨nat ping。Source Host和 Destination Host就是为了跨nat ping。在正常情况下,当设备发送 echo 请求时,这两个字段都设置为 0。如果 NAT 设备向另一台设备发送 Echo 请求,则中间框会将 Source Host 字段设置为其标识符(与地址的低 6 位匹配),以便将 Echo 回复路由回 NAT 设备。如果设备想要向 NAT 设备发送 echo 请求,则必须将 Destination Host 字段设置为 NAT 设备的标识符,并将 echo 请求发送到中间盒。在将请求转发到目标 NAT 设备之前,中间框会自动将 Destination Host 字段设置为零。当目标 NAT 设备返回回声回复时,中间框将使用 NAT 设备的标识符重写该字段,并将响应转发回发起回声请求的设备。


最后介绍tudp协议。
(参见图4)

这个报文头简单,无需过多讲解。校验和需要涵盖tudp头部和他的数据。tudp最大允许28字节的数据,从而可以在单片机上高效运行。


znet其余的设计以后补充。

znet主要用途是研究和学习,以及让单片机联网。znet目前还没有被实现,我会尽快实现他。欢迎大家一起探讨,研究,使用,提出修改意见!
本人是业余爱好者,znet可能有不完善之处,请大家尽管提出

国芯人工智能 发表于 2025-3-16 18:23:00

您的设计思路体现了对嵌入式系统网络通信的深入理解,尤其是在资源受限的51单片机上实现联网功能。Znet协议栈的轻量化设计,特别是对MTU的最小要求仅为48字节,使其在串口和红外等低带宽链路上具有较高的实用性。采用大端序的报文字段设计,确保了跨平台兼容性,这对于爱好者学习和实验网络原理非常有益。<br><br>Znet的分层架构和分组交换网络特性,使其能够支持数据包的多跳转发,这对于构建私有组织内网络是一个重要优势。与IP网络相比,Znet的私有性设计避免了IP地址占用问题,更适合特定场景的应用。总体而言,Znet协议栈为51单片机联网提供了一种高效且灵活的解决方案,具有较高的实用价值和探索空间。<br><br>[本文内容由国芯人工智能辅助生成,仅供参考]

lzzasd 发表于 2025-3-21 14:57:48

有具体的示例代码吗    如怎么握手   怎么传输    怎么结束

vb2002 发表于 2025-4-9 20:51:39

膜拜大佬.
页: [1]
查看完整版本: 为了让51单片机联网,自己设计了一个轻量的网络协议栈