调用Modbus读取保持寄存器触发IndexOutOfRangeException,需排查哪些项?
问题场景
执行以下Modbus读取代码时抛出System.IndexOutOfRangeException:
var factory = new ModbusFactory(); _master = factory.CreateMaster(new TcpClient(_ip, _port)); _master.ReadHoldingRegisters(1, 49, 7);
异常信息:
XXX初始化失败,异常信息:System.IndexOutOfRangeException: 索引超出了数组界限。
堆栈跟踪:
堆栈跟踪:
at nmodbus.io.modbustransport.createresponse[T] (Byte[] frame)
at nmodbus.io.modbusiptransport.createmessageandinitialuzetransactionid[T] (Byte[] fullFrame)
at nmodbus.io.modbustransport.unicastmessage[T] (IModbusMessage message)
at nmodbus.device.modbusmaster.perfomreadregisters(readholdinginputregistersrequest request)
at nmodbus.device.modbusmaster.readholdingregisters(byte slaveaddress, uint16 startaddress, uint16 numberofpointa)
at chillermonitor.unisemchillermonitor.init(cancellationtoken token) in d:\projects\service.chiller\chillermonitor\unisemchillermonitor.cs:line 91
需要检查的内容
- 验证从站寄存器范围与地址规则
确认Slave地址1的设备,是否存在起始地址49开始的7个保持寄存器。注意设备文档的地址可能是1基,但NModbus默认用0基参数传入,比如设备标注的地址49(1基),代码里要传48。同时确认设备总保持寄存器数量不小于起始地址+读取数量(按对应地址规则计算)。 - 检查NModbus版本与协议兼容性
旧版NModbus存在解析异常响应帧的bug,可能导致数组越界。尝试升级到最新稳定版,同时确认设备使用标准Modbus TCP帧格式,无自定义扩展。 - 确认TCP连接完整性
网络丢包、延迟过高会导致接收的响应帧不完整,触发解析时的数组越界。可以在创建TcpClient后检查连接状态,添加简单的重试逻辑,排查网络环境是否稳定。 - 核对读取参数的合法性
确认第三个参数(读取寄存器数量)未超出设备单次读取的上限,虽然7个在标准Modbus的125个上限内,但部分设备有自定义限制,需核对设备手册。 - 验证从站地址正确性
若Slave地址错误,设备返回的异常响应可能被NModbus错误解析,引发越界。用Modbus调试工具(如Modbus Poll)传入相同参数测试,确认设备是否正常响应。
内容的提问来源于stack exchange,提问作者Iris Yellin

