84

关闭或重置 TcpClient 连接的正确方法是什么?我们有与硬件通信的软件,但有时会出现问题,我们不再与它通信,直到我们重新启动软件。

我曾尝试强制 TcpClient.Close() 甚至将其设置为 null 但这不起作用。只有完全重新启动软件才能工作。

建议?


我不能使用 using 关键字,因为 TpcClient 仅在一个位置定义,但在整个库中都使用。(并且在任何给定时间只有一个连接)

这是一个处理通信的库。软件本身可以调用Controller类(代表硬件)的ResetConnection()方法。

目前看起来像

if (tcpClient != null)
{
    tcpClient.Close();
    tcpClient = null;
}

现在从我在这里读到的内容,我应该使用 tcpClient.Dispose() 而不是“= null”

我会尝试一下,看看它是否有所作为。

4

8 回答 8

98

您必须在关闭连接之前关闭流:

tcpClient.GetStream().Close();
tcpClient.Close();

关闭客户端不会关闭流。

于 2009-12-30T14:44:49.223 回答
29

鉴于已接受的答案已过时,并且我在其他答案中看不到任何关于此的答案,因此我正在创建一个新答案。在 .Net 2 及更早版本中,您必须在关闭连接之前手动关闭流。该错误在 C# 的所有更高版本中都已修复,并且如Close 方法TcpClient的文档中所述,对该方法的调用会关闭连接和流Close

根据 Microsoft Docs 编辑

Close 方法将实例标记为已释放,并请求关联的 Socket 关闭 TCP 连接。根据 LingerState 属性,当数据仍有待发送时,调用 Close 方法后 TCP 连接可能会保持打开状态。当基础连接完成关闭时,不会提供任何通知。

调用此方法最终会导致关联的 Socket 关闭,并且还会关闭关联的用于发送和接收数据的 NetworkStream(如果已创建)。

于 2016-03-22T09:59:02.880 回答
22

用词:using。编程的好习惯。

using (TcpClient tcpClient = new TcpClient())
{
     //operations
     tcpClient.Close();
}
于 2009-01-08T18:42:13.183 回答
11

尽管有所有适当的using语句,调用Close,有一些指数回退逻辑并重新创建TcpClient我仍然看到应用程序无法在没有应用程序重新启动的情况下恢复 TCP 连接的问题。它一直以 System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

但是有一个选项看起来它可能已经解决LingerStateTcpClient这个问题(可能几个月都不知道,因为我自己的硬件设置经常失败!)。请参阅MSDN

// This discards any pending data and Winsock resets the connection.
LingerOption lingerOption = new LingerOption(true, 0);

using (var tcpClient = new TcpClient 
       {SendTimeout = 2000, ReceiveTimeout = 2000, LingerState = lingerOption })
   ...
于 2018-01-17T16:34:05.503 回答
6

除了一些内部日志,Close == Dispose。

Dispose 调用 tcpClient.Client.Shutdown( SocketShutdown.Both ),但它会吃掉任何错误。也许如果你直接调用它,你可以得到一些有用的异常信息。

于 2009-01-09T14:35:40.367 回答
6

关闭套接字连接并允许重新使用套接字:

tcpClient.Client.Disconnect(false);
于 2009-08-13T23:57:19.080 回答
6

关闭套接字以便重新打开的正确方法是:

tcpClient.Client.Disconnect(true);

布尔参数指示是否要重用套接字:

断开方法使用

于 2016-06-24T06:25:38.147 回答
1

您是否尝试过显式调用TcpClient.Dispose()

你确定你有 TcpClient.Close() 和 TcpClient.Dispose()-ed ALL连接吗?

于 2009-01-08T18:16:40.583 回答