ShipModul 的 Miniplex-3Wi 强制关闭 TCP 连接
Posted
技术标签:
【中文标题】ShipModul 的 Miniplex-3Wi 强制关闭 TCP 连接【英文标题】:TCP connection forcibly closed by ShipModul's Miniplex-3Wi 【发布时间】:2021-12-09 11:22:32 【问题描述】:我们一直在使用 C# 开发 .NET Framework 4.6.1 应用程序,其任务之一是通过局域网连接(Wi-Fi 或以太网)将 NMEA 0183 语句发送到多路复用器。该应用程序可以配置为使用 TCP 或 UDP 进行连接。应用程序和多路复用器之间的通信通过 UDP 工作数小时没有任何问题,但 TCP 连接存在这个问题,即我在自己的测试场景中使用的 ShipModul 的多路复用器在大约 10 或 15 分钟后强行关闭连接。此外,该应用程序的其他用户已经确认,当应用程序配置为使用 TCP 时,其他多路复用器可能根本无法工作,但 UDP 连接仍然可以正常工作。从 .NET Framework 应用程序到多路复用器的通信是单向的。
TCP 连接过早关闭的原因可能是什么?是否有一些要求和机制来主动保持连接处于活动状态,而不仅仅是当 IP 数据包从 PC 到达时假定它处于活动状态?如果需要主动维护连接,那么如何使用 .NET TcpClient
对象呢?
简单地说,代码类似于(仅在使用 TCP 时执行):
// connection initilization
tcpClient = new TcpClient(new IPEndPoint(unicastAddress.Address, port));
tcpClient.Connect(ipAddress, port);
networkStream = tcpClient.GetStream();
// ..prepare the NMEA sentence data..
networkStream.Write(asciiEncodedNmeaData, 0, asciiEncodedNmeaData.Length);
代码对应的UDP协议版本(仅在使用UDP时执行):
// connection initialization
udpClient = new UdpClient(new IPEndPoint(unicastAddress.Address, port));
udpClient.Connect(ipAddress, port);
// ..prepare the NMEA sentence data..
udpClient.Send(asciiEncodedNmeaData, asciiEncodedNmeaData.Length);
此外,当应用程序关闭/暂停时,Close()
方法会在上述任一客户端对象上调用,具体取决于所使用的协议(当应用程序取消暂停时,一切都将按上述方式重新启动):
tcpClient.Close();
networkStream.Close();
或:
udpClient.Close();
然后,大约 15 分钟后出现以下异常: System.IO.IOException: '无法将数据写入传输连接:现有连接已被远程主机强制关闭。'
【问题讨论】:
tcp 中没有任何东西会导致这种情况。您是否正确格式化了 tcp 发送? Nmea 有可变长度的句子,并且您没有检查是否发送了所有字节。多路复用器如何知道它收到了一个完整的句子?是换行符吗? 【参考方案1】:这是标准情况。 TCP 连接是有状态的,即消耗有限的资源,如内存。这就是为什么网络设备通常会丢弃不活动的连接。在您的情况下,“大约 10 或 15 分钟后”连接被认为是空闲的。
为避免这种情况,您可以发送“保持活动数据包”。只需通过计时器将任何数据(越少越好)写入networkStream
,例如每 5 分钟一次。
【讨论】:
以上是关于ShipModul 的 Miniplex-3Wi 强制关闭 TCP 连接的主要内容,如果未能解决你的问题,请参考以下文章