我编写了 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/