【发布时间】:2017-11-06 17:00:12
【问题描述】:
我有一个长时间运行的 TCP 连接。一台机器(物联网设备)与服务器建立连接,建立连接(加密和东西)并存储数据,连接保持打开一段时间。
一切正常,但有时服务器会“断开”连接并出现错误: 已建立的连接被主机中的软件中止(代码:10053 - ConnectionAborted)。但连接没有断开,因为服务器可以在错误后从设备读取数据并可以开始发送再次。如果连接真正断开,服务器和客户端都需要重新初始化连接(安全性和其他东西)。
没有什么能真正表明为什么网络流不能被写入。 并且轮询套接字说它是可写的,并且在下一点它会引发异常。似乎是随机发生的。
public class ClientIdentifier
{
...
public TcpClient Connection { get; set; }
public BlockDecoder ConnectionDecoder { get; set; }
}
private void ReplyToClient(ClientIdentifier client, byte[] data)
{
byte[] encrypted = client.ConnectionDecoder.Encrypt(data);
var stream = client.Connection.GetStream();
int dataIndex = 0;
while (dataIndex != encrypted.Length)
{
if (CanWriteClient(client))
{
byte[] block = encrypted.GetChunk(dataIndex, Frame.BLOCK_LENGTH);
stream.Write(block, 0, Frame.BLOCK_LENGTH);
dataIndex += Frame.BLOCK_LENGTH;
}
}
}
private bool CanWriteClient(ClientIdentifier client)
{
try
{
return client.Connection.Client.Poll(1000, SelectMode.SelectWrite);
}
catch (Exception ex)
{
Logger.Warn(ex, $"[{client.HexIdentifier}]: Polling client write failed");
return false;
}
}
编辑(2017 年 11 月 12 日)
服务器:192.168.1.150 设备:192.168.1.201
我可以看到,当服务器以某种奇怪的方式重置 Seq 和 Ack 时,设备会发送 RST。
【问题讨论】:
-
服务器应用程序必须在关闭套接字后重新打开套接字。客户端不会自动重新连接。
-
不是这样的,他们可以连接...但是有时通信会失败,问题是为什么。上面的代码告诉“如果可以就写,如果不能就等待”——它失败了。
-
你所描述的听起来像是一个奇迹。我想到的唯一假设是您有一些连接层可以重新建立与服务器的连接。我认为使用wireshark或tcpdump在服务器上进行数据包跟踪对您有帮助
-
您确定是服务器断开连接而不是客户端断开连接吗?
-
设备制造商告诉我们,我们的服务器发送了一个 TCP RST 数据包...如果我记得正确的套接字异常,代码 10053 来自主机(服务器)并且 ...54 是远程?