Я написал службу Windows, которая выполняет функцию функции Modbus WriteMultipleRegisters через TCP, используя библиотеку NModbus для трехсторонних устройств каждые 10 минут (тики System.Threading.Timer).C# Modbus/tcp - висящее соединение
Иногда это соединение повесьте трубку, как правило, во время сетевых проблем. Поскольку устройство принимает только одно соединение Modbus вовремя, а другим отказано, соединение во время всех следующих тиков завершается с ошибкой SocketException - ConnectionRefused.
Но устройство автоматически закрывает соединения, которые не реагируют после короткого времени. Что-то должно держать связь открытой на моей стороне даже на два дня. Более того, когда моя служба перезагружается, все снова хорошо. Таким образом, есть определенно некоторая забытая открытая связь. Но мне не удалось воспроизвести эту ошибку в dev, поэтому я не знаю, где/когда ... соединение зависает. Я знаю только, что следующее соединение отказано.
Я делаю вызов функции 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.
Поскольку я использую использование выражения, команда dispose вызывается для обоих объектов. Я посмотрел прочный NModbus исходный код, и все расположено правильно.
Любая идея, насколько возможно, что с этим подключением кода не закрыт?
Вы _sure_, что '.Dispose' предполагается закрыть соединение? Я столкнулся с этой проблемой с другой сетевой библиотекой. Это может просто очистить ресурсы, не на самом деле «закрывая» что угодно. – nemec
Да, я последовал за этим. Вызвать библиотеку вызовов и библиотеку TcpClient.Dispose. NModbus использует библиотеку unme для утилизации (файл: https://code.google.com/p/unme/source/browse/trunk/src/Unme.Common/DisposableUtility.cs) – Rfilip
'Shutdown' и' Dispose' являются двумя очень различные методы. 'Shutdown' отправляет сообщение« мы закончили »на другой конец, в то время как' Dispose' не всегда гарантирует это.Кроме того, отдельно от любых проблем с C# не забывайте, что TCP-соединения фактически не закрыты до истечения времени ожидания (чтобы не допустить, чтобы данные, зависающие в интернет-инфраструктуре, доставлялись в недавно открытое соединение на том же порту). Очень важно обрабатывать изящное завершение работы, поскольку любые затяжные TCP-соединения могут занять 2-4 минуты, чтобы фактически закрыть очередь .NET finalizer ... – Luaan