How to reuse socket in .NET?

31,175

Solution 1

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)

Solution 2

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.

Solution 3

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

client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Share:
31,175
Admin
Author by

Admin

Updated on December 12, 2020

Comments

  • Admin
    Admin over 3 years

    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?

  • Admin
    Admin about 14 years
    Funny thing is there is no such property or method called 'DontLingerSocket'. The closest thing to it is a property called 'LingerState'. You can instantiate a 'LingerOption' though and set that to it, but it doesn't make any difference if you try to reconnect after calling 'Disconnect'. And you can't reuse a socket if you call 'Close' because that will dispose of the socket.
  • KMån
    KMån about 14 years
    @Hermann: I think you will have to wait for some seconds(timeout) for the socket to be "reuseable", you can try putting your socket into a thread - for retries... just thinking; read more about the graceful shudown, msdn.microsoft.com/en-us/library/ms738547(VS.85).aspx
  • Scott Chamberlain
    Scott Chamberlain almost 11 years
    A space was lost there, it should have been two words "DontLinger" and "Socket". A better way to phrase that sentence is "...calling Shutdown, you can set the SocketOption named DontLinger to false and specify a nonzero ..."
  • James
    James almost 10 years
    @ScottChamberlain duly noted.
  • Jesse Chisholm
    Jesse Chisholm over 9 years
    NOTE: client.Connected is defined to be the connection state as of the most recent Send or Receive, not the current state. And since you just called Disconnect the messages should be "We were connected." and "We weren't connected".
  • Brain2000
    Brain2000 almost 5 years
    There's a "DontLinger" option and a "Linger" option. So if DontLinger should be false, then Linger should be true. Do you need to set just one or both of them? I feel whomever engineered this was smoking crack.