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

发布于 2024-08-11 09:19:55 字数 609 浏览 5 评论 0原文

我有一个 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。

什么是正确的做法?

I have a TcpClient object which sends some data to server, using its underlying NetworkStream.Write().
Therefor, I have:

TcpClient server = new TcpClient(serverName, 50001);

/* ... */

NetworkStream stream = server.GetStream();

Now, when a button is pressed, the connection should close.
What is the right way to close the connection? The MSDN docs say that closing the TcpClient (with .Close()) does not in fact close the socket, only the TcpClient resources (that's at least the way I understood the docs).

So, would doing the next code correctly close the connection?

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

Is this enough, or should I first check (somehow) if the stream (or server) can be closed (in case the connection is half-open or something)...

Even more, NetworkStream.Close() MSDN docs states that it releases resources (even sockets), so maybe closing the stream would be enough, taken that I prevent using the TcpClient after that point.

What is the right approach?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

如果没结果 2024-08-18 09:19:55

作为 文档 说:

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

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

不过,先关闭 NetworkStream 永远不会有什么坏处。

顺便说一句,如果您碰巧仅在一个方法中使用 TcpClient,请将其包装在 using( ) 语句中,以便您确定 Dispose() (相当于to Close()) 被调用,即使抛出异常等。

As the docs say:

Calling this method will eventually result in the close of the associated Socket and will also close the associated NetworkStream that is used to send and receive data if one was created.

So server.Close(); will be enough.

Closing the NetworkStream first will never hurt though.

By the way, if you happen to be using the TcpClient only in one method, wrap it in a using( ) statement so that you're sure Dispose() (equivalent to Close()) is called on it, even if exceptions are thrown etc.

一页 2024-08-18 09:19:55

我将把 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();
}

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

摘自如何关闭 TCP 套接字

I will associate a TCP connection with a socket.

Generally, the procedure is like this:
1. Finish sending data
2. Call Socket.Shutdown with SocketShutdown.Send parameter
3. Loop on Receive until it returns 0 or fails with an exception
4. Call Close()

Here's a small sample in pseudo code that is very similar to 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();
}

If first and third steps are skipped - data loss can happen.

Taken from How to close TCP socket

浅唱々樱花落 2024-08-18 09:19:55

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

不要忘记冲水!

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

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

You're right in closing the stream then the server. This should result in all sockets being closed successfully over time, as the documentation states. However, several head scratching bugs have taught me the important lesson over time:

Don't forget to flush!

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

You will often lose some data you thought you might have sent otherwise. This also helps ensure that the stream should be empty and inactive when you close it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文