How to reuse socket in .NET?

I am trying to reconnect to a socket that I have disconnected from but it won't allow it for some reason even though I called the Disconnect method with the argument "reuseSocket" set to true.

_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.Connect(ipAddress, port);
//...receive data
_socket.Disconnect(true); //reuseSocket = true
//...wait
_socket.Connect(ipAddress, port); //throws an InvalidOperationException:

Once the socket has been disconnected, you can only reconnect again asynchronously, and only to a different EndPoint. BeginConnect must be called on a thread that won't exit until the operation has been completed.

What am I doing wrong?

Answers


You can set the socket options like this

_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, True)

If it does not work, try some other options

_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, false)
_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, True)
_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 500)
_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, Timeout)

After reading the MSDN documentation for Socket.Disconnect I noticed something that might be causing your issue.

If you need to call Disconnect without first calling Shutdown, you can set the SocketOption named DontLinger to false and specify a nonzero time-out interval to ensure that data queued for outgoing transmission is sent. Disconnect then blocks until the data is sent or until the specified time-out expires. If you set DontLinger to false and specify a zero time-out interval, Close releases the connection and automatically discards outgoing queued data.

Try setting the DontLinger Socket option and specify a 0 timeout or use Shutdown before you call disconnect.


Did you try adding this line after Disconnect and before Connect?

client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

From MSDN:

// Release the socket.
client.Shutdown(SocketShutdown.Both);

client.Disconnect(true);
if (client.Connected) 
    Console.WriteLine("We're still connnected");
else 
    Console.WriteLine("We're disconnected");

If you are using a connection-oriented protocol, you can use this method to close the socket. This method ends the connection and sets the Connected property to false. However, if reuseSocket is true, you can reuse the socket.

To ensure that all data is sent and received before the socket is closed, you should call Shutdown before calling the Disconnect method.

Socket.Shutdown method waits until all the data in the buffer has been sent or received. However, if we only set linger options, the Socket will shutdown after certain timeout interval.


Need Your Help

Why do my Rspec tests fail after Rails 4 upgrade?

ruby-on-rails rspec ruby-on-rails-4 factory-bot

I recently upgraded my Rails application to Rails 4 and in my Rspec test suite one line is causing an error: