hswkcg 发表于 2018-5-23 19:22:32

LWIP UDP如何发送长度超过1500字节的数据?

环境:STM32F7 + FREERTOS + LWIP UDP

在使用UDP发送数据时,发现发送长度比较大的数据时PC端的网络助手收不到数据,一直找BUG,最后看到网上说UDP发送最大长度就1472个字节左右,不能超过1500个,但是肯定有这方面的应用啊,,

看到很多人说分包发送,还有说可以直接发送4K左右的数据,顿时就感觉混乱了。。。。

请教一个各位大侠,

1.LWIP中UDP最大的发送长度是否受限于MTU ? 发送长度缓存是否可以配置,如果可以在哪配置呢?

2. 如果需要分包发送,分包是个什么原理?如果分包发不就相当于是多帧了吗?


大家一起讨论啊,火花是碰撞出来的哟。。。。。


hswkcg 发表于 2018-5-29 17:39:10

本帖最后由 hswkcg 于 2018-5-29 17:42 编辑

结贴:

感谢 @armstrong@gushuailove @kanprin 以及各位大侠的秘籍指导!!

先说下明确的理论点:

1.LWIP UDP 自带分片功能,通过opt.h中的IP配置部分中的 IP_FRAGIP_REASSEMBLY两个宏定义使能打开;

2. UDP可以发送超过MTU的数据,最大长度收到IP包长度的限制,两字节0xFFFF,len = 理论长度 2^16 - udp head - iphead(未确认),

3.UDP发送超过1500 - 20(IP头)- 8(UDP头)=1472字节长度时,常用的PC端的网络助手收不到,但是抓包可以很明显看出分片发送的数据,至于为什么PC端软件收不到,还需再搞一下;

附上抓包的截图

接下来就搞UDP的同一个PORT的收发同时进行了。。。。



armstrong 发表于 2018-5-23 19:27:41


STM32F7这么高级的单片机,拥有的资源足以开启lwip所有特性了;你只要配置两个宏为1就行了:
/**
* IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that
* this option does not affect outgoing packet sizes, which can be controlled
* via IP_FRAG.
*/
#define IP_REASSEMBLY               (1)

/**
* IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note
* that this option does not affect incoming packet sizes, which can be
* controlled via IP_REASSEMBLY.
*/
#define IP_FRAG                     (1)

t3486784401 发表于 2018-5-23 19:28:45

TCP/UDP 都是流式玩意,你发送时分包/或者不分包,接收端都不能保证一定是整个包(粘包BUG)/或者多个包(断包BUG)。

TCP 在协议层只能保证收到包的先后、字节先后是对的,其他保证不了;

UDP 在协议层连包能不能收到都保证不了,需要你自己定义应答重发机制。


LWIP 属于轻型协议栈,应该也是上边的尿性

至于怎么设计数据流,保证正确识别出各个帧,这就是你数据结构的事了,一般是帧头帧尾帧序号帧校验啥的。

armstrong 发表于 2018-5-23 19:32:39

分包是IP层(网际层)的完成事情,而UDP(传输层)不用管,不受限于MTU。
不过,必须要有足够多的RAM才能稳定的让IP层拆包和分包;不然会增加软件的不稳定。

hswkcg 发表于 2018-5-23 19:34:59

armstrong 发表于 2018-5-23 19:27
STM32F7这么高级的单片机,拥有的资源足以开启lwip所有特性了;你只要配置两个宏为1就行了:
...

这个在opt.h中已经定义了啊,IP分片部分的宏定义
/**
* IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that
* this option does not affect outgoing packet sizes, which can be controlled
* via IP_FRAG.
*/
#if !defined IP_REASSEMBLY || defined __DOXYGEN__
#define IP_REASSEMBLY                   1
#endif

/**
* IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note
* that this option does not affect incoming packet sizes, which can be
* controlled via IP_REASSEMBLY.
*/
#if !defined IP_FRAG || defined __DOXYGEN__
#define IP_FRAG                         1
#endif

hswkcg 发表于 2018-5-23 19:37:50

armstrong 发表于 2018-5-23 19:32
分包是IP层(网际层)的完成事情,而UDP(传输层)不用管,不受限于MTU。
不过,必须要有足够多的RAM才能稳 ...

就是UDP发送数据长度不受限于MTU?

我发送1000字节数据在网络助手上可以收到,发送1500就收不到,wireshark抓包可以看到有UDP 1500字节数据,换了个网络助手也收不到

是不是UDP发送超过MTU长度数据时需要配置发送缓存大小?

UDP有最大发送限制吗?

armstrong 发表于 2018-5-23 19:38:15

hswkcg 发表于 2018-5-23 19:34
这个在opt.h中已经定义了啊,IP分片部分的宏定义
/**
* IP_REASSEMBLY==1: Reassemble incoming fragmen ...

移植开源软件时,原则上是不要去改动别人的源码核心文件的。
opt.h就属于它的核心文件。正确的做法是把这些宏定义在lwipopts.h文件中,而opt.h文件里本来就有#include "lwipopts.h"

armstrong 发表于 2018-5-23 19:42:49

hswkcg 发表于 2018-5-23 19:37
就是UDP发送数据长度不受限于MTU?

我发送1000字节数据在网络助手上可以收到,发送1500就收不到,wiresh ...

UDP最大包受限于IP报文,最大65KB。当然,前提是你有比65KB更大的RAM给lwip用于组合IP碎片!

armstrong 发表于 2018-5-23 19:44:44

而且IP层不保证数据一定能被目标收到,如果一个大UDP报文分片为100个IP碎片发送出去,只要在网络中丢失任意1个碎片,那么整个UDP报文就不能完成组装了,也就废掉了。

armstrong 发表于 2018-5-23 19:49:58

由此可以得出,程序应该尽量避免使用超过MTU(还要减去ETH报文头+IP报文头+UDP报文头)大小的UDP包。
因为UDP本来就是无连接的,所以程序用小包来设计协议,一样能完成无限数据的传输。

hswkcg 发表于 2018-5-23 19:51:52

armstrong 发表于 2018-5-23 19:38
移植开源软件时,原则上是不要去改动别人的源码核心文件的。
opt.h就属于它的核心文件。正确的做法是把这 ...

嗯,谢谢,

LWIP会优先使用lwipopts.h,然后在使用opt.h ,

只要这两个里面有一个出现相应宏定义就可以的

我理解的UDP发送较长数据包的分片和您的思路是一致的,但是我不清楚的是,为什么发送1400字节就可以收到,但是发送超过1500的就不可以


分片导致错误?这个肯定有应用需求的,不应该这么不可靠的啊

armstrong 发表于 2018-5-23 19:53:53

本帖最后由 armstrong 于 2018-5-23 20:28 编辑

楼上网友说lwip的尿性;其实在我多年经验看来,它的稳定性关键在于其移植代码和以太网驱动代码。
我的移植就能保证,任你在网络上对我的lwip设备如何攻击(必须隔着网线,关电源不算{:lol:} ),我的程序就是不会出故障。
不稳定只是人们没有深入(没有时间没有精力)了解lwip而已。

hswkcg 发表于 2018-5-23 19:54:38

armstrong 发表于 2018-5-23 19:49
由此可以得出,程序应该尽量避免使用超过MTU(还要减去ETH报文头+IP报文头+UDP报文头)大小的UDP包。
因为U ...

如果使用小包的话,那怎么分包呢?

把1500字节分成两个750包发送的话,不就是两帧UDP数据了吗?

还需要制定分包协议,接收端再依据协议组合?这样实现会很麻烦的

armstrong 发表于 2018-5-23 19:57:14

hswkcg 发表于 2018-5-23 19:54
如果使用小包的话,那怎么分包呢?

把1500字节分成两个750包发送的话,不就是两帧UDP数据了吗?


开启了IP_FRAG特性之后,是由lwip负责分包发送的。应用程序透明的,不用管。

hswkcg 发表于 2018-5-23 19:58:54

armstrong 发表于 2018-5-23 19:53
楼上有些网友说lwip的尿性;其实在我多年经验看来,它的稳定性关键在于其移植代码和以太网驱动代码。
我的 ...


虽然我知道做一个伸手党很可耻。。。。。

但是,这块确实需要大神提点。。。。

您方便给点UDP传输长度超过1500字节的资料吗?简单资料,提供配置处理思路就OK

非常感谢!

armstrong 发表于 2018-5-23 19:59:39

hswkcg 发表于 2018-5-23 19:51
嗯,谢谢,

LWIP会优先使用lwipopts.h,然后在使用opt.h ,


1500字节当然不行,因为1500的UDP数据要发送出去,还要加上底层协议头(UDP头+IP头)的开销,大约40个字节。这就超过MTU了!
你发送1460字节就没问题。

hswkcg 发表于 2018-5-23 20:02:14

armstrong 发表于 2018-5-23 19:57
开启了IP_FRAG特性之后,是由lwip负责分包发送的。应用程序透明的,不用管。 ...

那就尴了个尬了。。。。

抓包可以看到UDP长度为1500的数据,数据对比也正确,

但是PC端的网络助手就是收不到。。。。


还需要再仔细研究研究。。。。。


头都大了。。。。还是先吃饭吧。。。


非常感谢您的指导,谢谢!!!

hswkcg 发表于 2018-5-23 20:03:27

armstrong 发表于 2018-5-23 19:59
1500字节当然不行,因为1500的UDP数据要发送出去,还要加上底层协议头(UDP头+IP头)的开销,大约40个字 ...

您这是发送长度能不能超过MTU ???


hswkcg 发表于 2018-5-23 20:07:43

armstrong 发表于 2018-5-23 19:59
1500字节当然不行,因为1500的UDP数据要发送出去,还要加上底层协议头(UDP头+IP头)的开销,大约40个字 ...

这画风转变的有点受不了啊。。。


今晚一直走在可以超过MTU的路上,突然调头,有点。。。。。。饿!!!

armstrong 发表于 2018-5-23 20:09:17

hswkcg 发表于 2018-5-23 20:02
那就尴了个尬了。。。。

抓包可以看到UDP长度为1500的数据,数据对比也正确,


wareshark截图看看?会不会1500标的是整个IP报文的字节数呢,这就是MTU。
一个UDP报文是这样的:
ETH头14字节+IP头20字节+UDP头8字节+UDP数据+CRC32

armstrong 发表于 2018-5-23 20:11:24

hswkcg 发表于 2018-5-23 20:07
这画风转变的有点受不了啊。。。




我说的情况是没有使能IP_FRAG的前提下。如果开启了IP_FRAG之后,你就能一次发送大于1472字节的UDP数据。

modbus 发表于 2018-5-23 22:34:47

分包发送是编通讯程序的基本功吧,不然发送上M的数据怎么办

hswkcg 发表于 2018-5-24 09:28:24

modbus 发表于 2018-5-23 22:34
分包发送是编通讯程序的基本功吧,不然发送上M的数据怎么办

关键是以前公司就涉及通讯这块。。。。。。

请教您一下,分包发送是不是需要分包协议?不然怎么确定是一帧分成几包发的,还是直接就是几帧呢?

gushuailove 发表于 2018-5-24 16:16:36

hswkcg 发表于 2018-5-23 19:37
就是UDP发送数据长度不受限于MTU?

我发送1000字节数据在网络助手上可以收到,发送1500就收不到,wiresh ...

wireshark抓包都能正常抓到?那就应该是正常发送了才对啊??

hswkcg 发表于 2018-5-24 17:16:53

gushuailove 发表于 2018-5-24 16:16
wireshark抓包都能正常抓到?那就应该是正常发送了才对啊??

wireshark 抓包是这样的,帧长度显示只有62字节,但是Data数据是全的,

这个软件用的少,不确定这个是不是全发出来

gsq19920418 发表于 2018-5-24 17:27:04

需要雙邊同時設置同樣的MTU,否則有可能出現不支持

hswkcg 发表于 2018-5-24 17:40:34

gsq19920418 发表于 2018-5-24 17:27
需要雙邊同時設置同樣的MTU,否則有可能出現不支持

我的测试环境是STM32F746Discovery开发板直接和PC连接

开发板的的PHY是LAN8742,MTU是1500,WIN7的MTU也是1500

好像这个不是必须一样的吧?网络接口好像一般都是576?

gushuailove 发表于 2018-5-24 21:10:15

问题应该不是IP层及以下(分包之类的),多看看是不是单片机程序缓存不够之类的,lwip提供的接口函数报错处全部加输出信息,看能不能看到哪个地方有返回错误被应用程序忽略掉了。

upli 发表于 2018-5-24 22:02:37

好像路由器里也会有最大包长的控制选项。分包应该不好控制,只能保证数据按顺序到达?

hswkcg 发表于 2018-5-25 09:07:30

upli 发表于 2018-5-24 22:02
好像路由器里也会有最大包长的控制选项。分包应该不好控制,只能保证数据按顺序到达? ...

是STM32F7的开发板和PC直接连的,

开始没有过路由器,后来想到是不是MTU不一致,就接上交换机试了一下也不行

lindabell 发表于 2018-5-25 13:03:57

为什么要一次发1500呢,即使能一次发1500,到接收那边也有可能分几次收到的。

hswkcg 发表于 2018-5-25 14:33:34

lindabell 发表于 2018-5-25 13:03
为什么要一次发1500呢,即使能一次发1500,到接收那边也有可能分几次收到的。 ...

这个和客户应用有关,把收到的2000字节的数据直接转发,不需要处理

风过不留痕z 发表于 2023-7-20 17:01:22

楼主,你的问题最后解决了吗?我这边也遇到了,好像是不能大于mtu设置的值,改了也没用

风过不留痕z 发表于 2023-12-26 08:54:09

armstrong 发表于 2018-5-23 19:53
楼上网友说lwip的尿性;其实在我多年经验看来,它的稳定性关键在于其移植代码和以太网驱动代码。
我的移植 ...
(引用自12楼)

请教一下,单片机和电脑网线直连的情况下,lwip的udp可以实现稳定的5ms发送一帧数据吗?wires hark抓出来的每帧间隔时间很不稳定
页: [1]
查看完整版本: LWIP UDP如何发送长度超过1500字节的数据?