简体   繁体   中英

What is the correct way to close a TCP connection

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?

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.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM