我已经编写了windows服务,它每10分钟使用NModbus库通过tcp向三方设备执行modbus writemultipleregisters函数调用(system.threading.timer的滴答声)。
有时这个连接会在网络出现问题时挂断。由于设备一次只接受一个Modbus连接,而其他连接被拒绝,因此在所有下一个滴答期间,连接都会失败,socketException-connectionRejected。
但设备会自动关闭短时间后不响应的连接。哪怕是两天,我也得有东西保持连接畅通。更重要的是,当我的服务重新启动时,一切都恢复正常。所以肯定有一些被遗忘的开放连接。但我没能在dev中重现这个bug,所以我不知道在哪里/什么时候……连接挂断。我只知道下一个连接被拒绝了。
我用这部分代码调用modbus函数:

using (TcpClient client = new TcpClient(device.ip, 502))
    {
    using (Modbus.Device.ModbusIpMaster master = Modbus.Device.ModbusIpMaster.CreateIp(client))
          {
          master.WriteMultipleRegisters(500, new ushort[] { 0xFF80 });
    }
}

device.ip是包含设备IP地址的字符串-它是正确的,已从SocketException详细信息中确认。
在我使用using语句时,对两个对象都调用dispose。
我浏览了nmodbus源代码,所有内容都被正确地处理了。
知道这个代码连接怎么可能没有关闭吗?

最佳答案

我同意nemec。如果您查看TcpClient.Disposeif的文档,没有特别提到关闭连接。默认情况下,它释放托管和非托管资源,但可能无法正确地断开连接。
尝试将代码更改为:

using (TcpClient client = new TcpClient(device.ip, 502))
{
    try
    {
        using (Modbus.Device.ModbusIpMaster master = Modbus.Device.ModbusIpMaster.CreateIp(client))
        {
            master.WriteMultipleRegisters(500, new ushort[] { 0xFF80 });
        }
    }
    catch(Exception e)
    {
        // Log exception
    }
    finally
    {
        client.Close();
    }
}

这样,在处理之前就可以进行清理关闭,即使modbus协议抛出某种异常,它也应该进行清理。

09-06 02:24