23

I have a server that listens for a connection on a socket:

public class Server { private Socket _serverSocket; public Server() { _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _serverSocket.Bind(new IPEndPoint(IPAddress.Any, 1234)); _serverSocket.Listen(1); } public void Start() { _serverSocket.BeginAccept(HandleAsyncConnectionMethod, null); } public void Stop() { //????? MAGIC ????? } //... rest of code here } 

What is the correct (clean) way to close down the socket?

Is it sufficient to call:

_serverSocket.Disconnect(true); 

in the Stop() method? or is there other work that needs to happen to close the connection cleanly?

7 Answers 7

4

TCP connection termination correctly involves a four-way handshake. You want both ends to inform the other that they're shutting down and then acknowledge each other's shutdown.

Wikipedia explains the process: http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_termination

This post explains how to make it happen in C#: http://vadmyst.blogspot.com/2008/04/proper-way-to-close-tcp-socket.html

Sign up to request clarification or add additional context in comments.

3 Comments

-1: A socket performing an accept (ie. awaiting new connections) is now the same as a socket connected to a client (where one of Disconnect or Shutdown is the right answer).
@Richard: Since you seem to be knowledgeable on what cases require certain actions, perhaps you could share an answer rather than just downvoting everyone elses. Despite being an older post, I'm sure the community would appreciate it since there are quite a few views on this question (I would be one of them).
@Ocelot20 1. See my comment (I include the information). 2. This is not the only answer to this question.
3

Since you are listening for incoming TCP connections, you could use System.Net.Sockets.TcpListener which does have a Stop() method. It does not have asynchronous operations though.

1 Comment

Looking at the internals (via a Telerick's decompiler) TcpListener.Stop just closes the underlying listening socket. How well this interacts with an outstanding asynchronous accept is unclear (but it seems to work).
3

2 ways to close it properly without exceptions

1) create temporary connecting socket and connect it to listening one so it could have its handler triggered then just finish it with normal EndAccept and after that close both.

2) just Close(0) listening socket which will result in false shot to its callback, if you then look into your listening socket you will see that its state is "closed" and "disposed". This is why calling EndAccept would cause exception. You may just ignore it and do not call EndAccept. Listening socket will go down immediately without timeout.

1 Comment

I added a volatile bool isShuttingDown, initially set to false. When the socket is terminating, I set that to true. Then in the Accept Callback, I check the value and do not call EndAccept if it is true. This works great with no exceptions.
0

The cleanest way to have Accept call break immediately is to call _serverSocket.Dispose(); Any other call to methods in the like of Shutdown or Disconnect will throw an exception.

Comments

-1

First, you need to make sure you're keeping track of any client sockets that were created in the process of BeginAccept. Shut those down first using the Socket.Shutdown() and Socket.Close() methods. Once those have all been shut down then do the same on the listening socket itself.

1 Comment

-1: No need to stop connected sockets when the listening (accepting) socket is closed. A server that only handles one client at a time could reasonably close the accepting socket while the one client is connected and then create a new listening socket for a new client.
-2

That should handle it...but if you need to make absolutely sure, you could always kill it with fire:

Not for sockets, but same idea applies., which is to close it in every way possible, then finally set the socket to null.

1 Comment

Wait, are you being funny like the codinghorror post, or do you really think it's a good idea to close it in every way possible and setting it to null?
-3

You should use Socket.Shutdown() and then Socket.Close(). Socket.Disconnect() is usually only used if you intend on reconnecting the same socket.

1 Comment

-1: A socket performing an accept (ie. awaiting new connections) is now the same as a socket connected to a client (where one of Disconnect or Shutdown is the right answer).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.