优化手机网站,网站建设加数据库,移动端seo,泰国vps最近在用GD32和管理机之间用TCP协议开发一个功能#xff0c;功能都没问题#xff0c;后面跑大量发包时候的连续测试时#xff0c;总是会出现偶发性的#xff0c;大概几分钟到数十分钟的一次丢包。尽管在应用层做了超时机制#xff0c;一旦超时就会重新建立socket链接并重新… 最近在用GD32和管理机之间用TCP协议开发一个功能功能都没问题后面跑大量发包时候的连续测试时总是会出现偶发性的大概几分钟到数十分钟的一次丢包。尽管在应用层做了超时机制一旦超时就会重新建立socket链接并重新发包但是这样做太丑陋了而且断开重连延时太大了还是想彻底搞清楚这个个问题。所以先抓包吧。
管理机使用TCP dump抓包要加-v选项不然后面无法从通信流程上看到问题所在最开始没加以为是其它问题愣是分析了半天也没想出所以然。注意cksum 0x5295 (incorrect - 0x0026的字样不是说我校验和没对而是校验和的计算是放在了mac控制器硬件计算而tcpdump抓包的时候处于mac计算之前所以这时候检验和不对是正常的这个功能叫做offload可以关闭的。 然后在GD32中打开lwip的debug选项也进行了抓包 抓完包之后进行分析由于篇幅有限就不放全部的抓包日志了跟大家讲下这中间发生了什么。
先看管理机tcpdump日志我的程序会发送数据位25字节大小的报文GD32收到并执行操作后返回12字节的报文就是一来一回这样收发。
可以看到前面25,12,25,12交替的报文收发是正常的但是突然就有这么一个包嘿发不出去了所以一直在重发重发很多次也收不到ack。直到什么时候才发出去呢直到我应用程序关闭了链接在TCP协议关闭前最后一次发送缓冲区的剩余内容时他发出去了并且收到了GD32的ack。
再来看看GD32的抓包简而言之除了那个管理机一直重发发不出去的包前后所有的包GD32都收到了。
后来我进行了多次试验实验结果均是如此。一开始我还没有注意校验和这个字段光分析TCP协议去了什么nolelay啊什么快速重传以及很多配置都用过了均失败了。后来吧tcpdump的-v选项打开偶然间看到发这个重传的包的校验和是0xffff卧槽这个可太敏感了不是什么0x1234也不是0x9876偏偏是这个十六位检验值的边界所以大胆假设只有校验和恰好是0xffff的才会丢包。再做做实验真的每次都是这个0xffff的包发不出去
于是我查阅手册把GD32的MAC控制器的硬件校验给关掉再把LWIP的软件校验给打开。 就不再丢包了并且再次遇到0xffff校验和的包也能够被收到了 所以我的结论就是GD32的MAC控制器的硬件校验存在bug只要遇到校验和0xffff的包就把他丢掉。解决办法关闭硬件校验使用LWIP的软件校验。
这也解释了为什么我关闭了socket链接反而能够将缓冲区的包发出去了因为关闭连接之后发的包flag字段不一样也就导致校验和不是0xffff所以能够被GD32接收。
同时后来我查约到了另一个网友的帖子GD32F407ZET6LAN8720DMA以太网移植LWIP协议栈UDP通信ping测试每65535包丢一包 - GD32 MCU - 电子工程世界-论坛 (eeworld.com.cn)
每65535丢一个包这不就是uint16的范围吗估计原因和我这个一样遇到0xffff了。所以啊估计GD32的不止一款芯片的MAC控制器有问题大家开发这个的时候注意别踩坑
后面问了代理商的技术支持暂未回复