搜索
bottom↓
回复: 34

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

[复制链接]

出0入0汤圆

发表于 2018-5-23 19:22:32 | 显示全部楼层 |阅读模式
环境:  STM32F7 + FREERTOS + LWIP UDP

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

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

请教一个各位大侠,

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

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


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


出0入0汤圆

 楼主| 发表于 2018-5-29 17:39:10 | 显示全部楼层
本帖最后由 hswkcg 于 2018-5-29 17:42 编辑

结贴:

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

先说下明确的理论点:

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

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

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

附上抓包的截图

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



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出870入263汤圆

发表于 2018-5-23 19:27:41 | 显示全部楼层

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

  7. /**
  8. * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note
  9. * that this option does not affect incoming packet sizes, which can be
  10. * controlled via IP_REASSEMBLY.
  11. */
  12. #define IP_FRAG                     (1)
复制代码

出200入2554汤圆

发表于 2018-5-23 19:28:45 | 显示全部楼层
TCP/UDP 都是流式玩意,你发送时分包/或者不分包,接收端都不能保证一定是整个包(粘包BUG)/或者多个包(断包BUG)。

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

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


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

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

出870入263汤圆

发表于 2018-5-23 19:32:39 | 显示全部楼层
分包是IP层(网际层)的完成事情,而UDP(传输层)不用管,不受限于MTU。
不过,必须要有足够多的RAM才能稳定的让IP层拆包和分包;不然会增加软件的不稳定。

出0入0汤圆

 楼主| 发表于 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

出0入0汤圆

 楼主| 发表于 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有最大发送限制吗?

出870入263汤圆

发表于 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"

出870入263汤圆

发表于 2018-5-23 19:42:49 | 显示全部楼层
hswkcg 发表于 2018-5-23 19:37
就是UDP发送数据长度不受限于MTU?

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

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

出870入263汤圆

发表于 2018-5-23 19:44:44 | 显示全部楼层
而且IP层不保证数据一定能被目标收到,如果一个大UDP报文分片为100个IP碎片发送出去,只要在网络中丢失任意1个碎片,那么整个UDP报文就不能完成组装了,也就废掉了。

出870入263汤圆

发表于 2018-5-23 19:49:58 | 显示全部楼层
由此可以得出,程序应该尽量避免使用超过MTU(还要减去ETH报文头+IP报文头+UDP报文头)大小的UDP包。
因为UDP本来就是无连接的,所以程序用小包来设计协议,一样能完成无限数据的传输。

出0入0汤圆

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

嗯,谢谢,

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

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

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


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

出870入263汤圆

发表于 2018-5-23 19:53:53 | 显示全部楼层
本帖最后由 armstrong 于 2018-5-23 20:28 编辑

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

出0入0汤圆

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

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

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

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

出870入263汤圆

发表于 2018-5-23 19:57:14 | 显示全部楼层
hswkcg 发表于 2018-5-23 19:54
如果使用小包的话,那怎么分包呢?

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

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

出0入0汤圆

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


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

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

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

非常感谢!

出870入263汤圆

发表于 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字节就没问题。

出0入0汤圆

 楼主| 发表于 2018-5-23 20:02:14 | 显示全部楼层
armstrong 发表于 2018-5-23 19:57
开启了IP_FRAG特性之后,是由lwip负责分包发送的。应用程序透明的,不用管。 ...

那就尴了个尬了。。。。

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

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


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


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


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

出0入0汤圆

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

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


出0入0汤圆

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

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


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

出870入263汤圆

发表于 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

出870入263汤圆

发表于 2018-5-23 20:11:24 | 显示全部楼层
hswkcg 发表于 2018-5-23 20:07
这画风转变的有点受不了啊。。。

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

出0入0汤圆

发表于 2018-5-23 22:34:47 | 显示全部楼层
分包发送是编通讯程序的基本功吧,不然发送上M的数据怎么办

出0入0汤圆

 楼主| 发表于 2018-5-24 09:28:24 | 显示全部楼层
modbus 发表于 2018-5-23 22:34
分包发送是编通讯程序的基本功吧,不然发送上M的数据怎么办

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

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

出0入0汤圆

发表于 2018-5-24 16:16:36 | 显示全部楼层
hswkcg 发表于 2018-5-23 19:37
就是UDP发送数据长度不受限于MTU?

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

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

出0入0汤圆

 楼主| 发表于 2018-5-24 17:16:53 | 显示全部楼层
gushuailove 发表于 2018-5-24 16:16
wireshark抓包都能正常抓到?那就应该是正常发送了才对啊??

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

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2018-5-24 17:27:04 | 显示全部楼层
需要雙邊同時設置同樣的MTU,否則有可能出現不支持

出0入0汤圆

 楼主| 发表于 2018-5-24 17:40:34 | 显示全部楼层
gsq19920418 发表于 2018-5-24 17:27
需要雙邊同時設置同樣的MTU,否則有可能出現不支持

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

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

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

出0入0汤圆

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

出0入0汤圆

发表于 2018-5-24 22:02:37 来自手机 | 显示全部楼层
好像路由器里也会有最大包长的控制选项。分包应该不好控制,只能保证数据按顺序到达?

出0入0汤圆

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

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

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

出0入8汤圆

发表于 2018-5-25 13:03:57 来自手机 | 显示全部楼层
为什么要一次发1500呢,即使能一次发1500,到接收那边也有可能分几次收到的。

出0入0汤圆

 楼主| 发表于 2018-5-25 14:33:34 | 显示全部楼层
lindabell 发表于 2018-5-25 13:03
为什么要一次发1500呢,即使能一次发1500,到接收那边也有可能分几次收到的。 ...

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

出0入0汤圆

发表于 2023-7-20 17:01:22 | 显示全部楼层
楼主,你的问题最后解决了吗?我这边也遇到了,好像是不能大于mtu设置的值,改了也没用

出0入0汤圆

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

请教一下,单片机和电脑网线直连的情况下,lwip的udp可以实现稳定的5ms发送一帧数据吗?wires hark抓出来的每帧间隔时间很不稳定
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-29 19:26

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表