什么是关闭TCP连接的正确方法

时间:2009-11-20 09:17:57

标签: c# tcp networkstream

我有一个TcpClient对象,它使用底层的NetworkStream.Write()将一些数据发送到服务器。 因此,我有:

TcpClient server = new TcpClient(serverName, 50001);

/* ... */

NetworkStream stream = server.GetStream();

现在,按下按钮时,连接应该关闭。 什么是关闭连接的正确方法? MSDN文档说关闭TcpClient(使用.Close())实际上并不关闭套接字,只关闭TcpClient资源(这至少是我理解文档的方式)。

那么,下一个代码会正确关闭连接吗?

stream.Close();
server.Close();

这是否足够,或者我应该首先检查(以某种方式)是否可以关闭流(或服务器)(如果连接是半开的或者某种东西)......

更多,NetworkStream.Close() MSDN文档声明它会释放资源(甚至是套接字),因此关闭流就足够了,因为我在此之后阻止使用TcpClient。

什么是正确的方法?

3 个答案:

答案 0 :(得分:6)

正如the docs所说:

  

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

所以server.Close();就够了。

首先关闭NetworkStream绝对不会受到伤害。

顺便说一句,如果您恰好只在一个方法中使用TcpClient,请将其包装在using( )语句中,以便您确定Dispose()(相当于Close())即使抛出异常等,也会调用它。

答案 1 :(得分:3)

我将TCP连接与套接字关联。

一般来说,程序是这样的:    1.完成发送数据    2.使用SocketShutdown.Send参数调用Socket.Shutdown    3.循环接收,直到它返回0或因异常而失败    4.调用Close()

这是伪代码中的一个小样本,与C#非常相似:)

void CloseConnection(Socket socket)
{
   socket.Send(/*last data of the connection*/);
   socket.Shutdown(SocketShutdown.Send);

   try
   {
      int read = 0;
      while( (read = socket.Receive(/*application data buffers*/)) > 0 )
      {}
   }
   catch
   {
      //ignore
   }
   socket.Close();
}

如果跳过第一步和第三步 - 可能会发生数据丢失。

取自How to close TCP socket

答案 2 :(得分:0)

关闭流然后关闭服务器是正确的。这应该会导致所有套接字随着时间的推移成功关闭,如文档所述。然而,随着时间的推移,几个头脑痒痒的错误教会了我一个重要的教训:

别忘了冲洗!

stream.Flush();
stream.Close();
server.Close();

您经常会丢失一些您认为可能已发送的数据。这也有助于确保在关闭流时应该为空并且不活动。