【发布时间】:2012-03-29 19:08:05
【问题描述】:
我正在编写一个小型 (C#) 客户端应用程序,它使用 TCP/IP 连接将数据发送到远程服务器。我正在使用标准的 .Net TcpClient 对象并希望从客户端保持连接打开,因为我定期向服务器提交数据包。但是,服务器可能会关闭连接,在这种情况下,我需要知道在发送下一个数据包之前重新连接。
使用 Wireshark,我可以(仅)在服务器终止连接时看到以下对话框:
server >>> FIN, ACK
ACK <<< client
我没有看到的是我的客户端用它自己的 FIN 响应,以完成连接关闭。结果是我的客户端程序在发送下一个数据包后才发现连接断开了。
有什么方法可以设置 TcpClient 或其底层 Socket 以完成断开连接,并提供一些反馈,以便我的客户端代码知道在发送下一个数据包之前重新连接?
添加以回应以下评论: 我的发送代码非常简单 - 维护 TcpClient 和 NetworkStream 成员变量的对象,有一个成员函数(基本上)包含以下内容:
bool sent = false;
byte[] buffer = Encoding.UTF8.GetBytes(dataString);
while (!sent)
{
try
{
m_outStream.Write(buffer, 0, buffer.Length);
sent = true;
}
catch (Exception ex)
{
if (m_outStream != null) { m_outStream.Dispose(); }
m_client = new TcpClient(AddressFamily.InterNetwork);
m_client.Connect(ipAddress, ipPort);
m_outStream = m_client.GetStream();
}
}
在 m_client 和 m_outStream 初始化后,每次只执行一次。然后使用 Wireshark,我可以看到服务器发送一个带有标志 FIN, ACK 的数据包,客户端用 ACK 响应该数据包。
下次我调用我的函数时,数据以PSH, ACK 发送出去,服务器以RST, ACK 响应但不读取传入的数据。客户端不会引发异常。
然后我再次调用我的函数,并引发异常导致重新启动连接。
【问题讨论】: