C# Modbus/tcp - 挂起连接

标签 c# tcp tcpclient modbus

我编写了 Windows 服务,它使用 NModbus 通过 TCP 执行 Modbus WriteMultipleRegisters 函数调用每 10 分钟将库传输到 3 方设备(System.Threading.Timer 的滴答声)。

偶尔这个连接会挂断,通常是在网络问题期间。由于设备一次只接受一个 Modbus 连接而其他连接被拒绝,因此所有下一个滴答期间的连接都会失败并出现 SocketException - ConnectionRefused。

但是设备会自动关闭短时间后没有响应的连接。即使是两天,也必须在我身边保持连接。更重要的是,当我的服务重新启动时,一切都恢复正常了。所以肯定有一些被遗忘的开放连接。但是我没有设法在开发中重现这个错误,所以我不知道在哪里/什么时候.. 连接挂断。我只知道下一个连接被拒绝。

我用这部分代码调用 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.Dispose 的文档如果没有特别提到关闭连接。默认情况下,它会释放托管和非托管资源,但它可能无法正确断开连接。

尝试将您的代码更改为:

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 协议(protocol)抛出某种异常,它也应该进行清理。

关于C# Modbus/tcp - 挂起连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20902505/

相关文章:

python - 读取时非阻塞 Python 套接字的超时值是多少?

c# - 客户端关闭连接时在服务器上多次调用 NetworkStream 回调

vb.net - TCP/IP 检测监听器上是否有当前连接的客户端

c# - 如何以编程方式将 TypedEventHandler 添加到 RoutedEvents?

apache - 80端口在服务器上打开但无法连接到它

c# - Web API 中的最佳/安全字符串长度

java -\n 之后的字符串根本没有显示在系统输出中

html - 返回html代码

c# - 你需要 "unwire"一个匿名函数/lambda

c# - 图像控件无法显示图像