news 2026/4/30 1:49:57

FreeModbus释放底层的 TCP 监听端口

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FreeModbus释放底层的 TCP 监听端口

背景

有Modbus和scpi两种协议,在使用过程中要切换,每次切换要给给对应协议绑定端口

问题

在每次切换协议之前都这样操作,把所有连接都关闭仔进行重新绑定

// 尝试禁用ModbuseMBDisable();// 尝试关闭SCPI服务器的监听和客户端连接if(server_state.listen_pcb!=NULL){tcp_close(server_state.listen_pcb);server_state.listen_pcb=NULL;}if(server_state.client_pcb!=NULL){tcp_close(server_state.client_pcb);server_state.client_pcb=NULL;server_state.connected=0;}

但是失败
结果:这样修改后,开机后protocol=1能直接连上设置的 192.168.1.111 port: 501 Modbus

面板改成选scpi后两种协议都不能使用,再改回Modbus后modbus可以使用,scpi不能用

开机后protocol=0能直接连上设置的 192.168.1.111 port: 501 scpi , 此时端口成功绑定

改成Modbus后modbus可以使用,scpi不能用

面板再改成选scpi后两种协议都不能使用,此时端口绑定失败

原因

这次失败的原因在于 FreeModbus 库的 eMBDisable() 函数默认只停止协议状态机,并不会释放底层的 TCP 监听端口(Listening Socket)。

  1. 资源未释放:在 Modbus TCP 模式下,eMBDisable()最终调用的是vMBTCPPortDisable(),而在porttcp.c中,这个函数仅尝试关闭已连接的客户端 PCB,完全没有处理正在监听的 PCB (pxPCBListen)
  2. 库配置限制:FreeModbus 默认将MB_PORT_HAS_CLOSE设置为0,这导致eMBClose()函数实际上是空的。
  3. 现象解释
    • 当从 Modbus 切换到 SCPI 时,Modbus 的监听端口依然在占用(因为它没被关闭)。
    • SCPI 尝试tcp_bind同一个端口,自然返回8(ERR_USE)。
    • 当切回 Modbus 时,Modbus 重新初始化并覆盖了之前的指针,但旧的监听 PCB 依然挂在协议栈里(资源泄露),虽然能连上,但此时协议栈状态已经非常混乱。

最终解决方法

我们需要强制开启 Modbus 库的资源释放功能,并在切换时显式调用它。

步骤 1:开启 Modbus 库的关闭功能

在 mbconfig.h中,将MB_PORT_HAS_CLOSE定义为1

添加了:

#defineMB_PORT_HAS_CLOSE(1)

步骤 2:在切换逻辑中添加彻底关闭调用

在 user_mb_app_m.c的cleanup_all_protocols函数中,添加对eMBClose()的调用。

核心修改如下:

staticvoidcleanup_all_protocols(void){// 1. 禁用 Modbus 状态机eMBDisable();// 2. 彻底关闭 Modbus 端口监听(关键:释放 pxPCBListen)eMBClose();// 3. 彻底清理 SCPI 资源if(server_state.client_pcb!=NULL){tcp_abort(server_state.client_pcb);server_state.client_pcb=NULL;server_state.connected=0;}if(server_state.listen_pcb!=NULL){tcp_close(server_state.listen_pcb);server_state.listen_pcb=NULL;}}

验证说明

  • 为什么这次会成功?
    • 因为eMBClose()会通过pvMBFrameCloseCur指针最终调用到porttcp.c中的vMBTCPPortClose()
    • vMBTCPPortClose()会显式调用prvvMBPortReleaseClient( pxPCBListen ),这才会真正向 LwIP 发出关闭监听端口的指令。
  • 后续测试
    再次切换。切换到 SCPI 后,观察到端口顺利绑定。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/30 1:49:56

Movelt2 规划场景 ROS API

文章目录前言一、使用rviz可视化二、ROS API1.发布所需话题2.定义附着碰撞物体的消息3.将一个对象添加到环境中4.同步更新和异步更新的区别5.将一个物体连接到机器人上6.从机器人上分离一个物体7.将物体从碰撞世界移除总结前言 本文整理的是 MoveIt2 官方示例 主要学习 添加和…

作者头像 李华
网站建设 2026/4/30 1:48:31

AEUX:5分钟从设计到动画的免费终极转换指南 ✨

AEUX:5分钟从设计到动画的免费终极转换指南 ✨ 【免费下载链接】AEUX Editable After Effects layers from Sketch artboards 项目地址: https://gitcode.com/gh_mirrors/ae/AEUX 你是不是经常面对这样的场景:在Figma中精心设计了完美的UI界面&am…

作者头像 李华
网站建设 2026/4/30 1:48:27

(十)Skills的魔法(下)— 从社区到自定义

(十)Skills的魔法(下)— 从社区到自定义系列第10篇 作者:挖AI金矿上篇文章我们讲了如何创建和管理自己的Skill。但一个人的力量总是有限的——Hermes Agent真正强大的地方,在于它有一个活跃的社区生态&…

作者头像 李华
网站建设 2026/4/30 1:46:26

AI Agent框架探秘:拆解 OpenHands()--- Runtime主要组件

一、前言:什么是 OFA VQA 模型? OFA(One For All)是字节跳动提出的多模态预训练模型,支持视觉问答、图像描述、图像编辑等多种任务,其中视觉问答(VQA)是最常用的功能之一——输入一张…

作者头像 李华
网站建设 2026/4/30 1:45:24

3分钟快速解密网易云音乐NCM格式:ncmdump工具完整使用指南

3分钟快速解密网易云音乐NCM格式:ncmdump工具完整使用指南 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM加密文件无法在其他播放器播放而烦恼吗?ncmdump工具就是你的救星&#xf…

作者头像 李华