TCP Socket.Bind() Exception

Hello all, I’m doing some further TCP stress testing and I noticed a replicable exception using the Socket.Bind() method.

I’m hosting a TCP server on the local network. When I create the socket and call the bind method the first time, everything seems to work okay. If I manually close the TCP connection (say the ethernet connection closes), and then reopen the server later, the .Bind() method throws an invalid operation exception as shown below:

Code Throws Exception

IPEndPoint ServerEndpoint = new IPEndPoint(EthernetController.IpAddress, tcpPort);
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_serverSocket.Bind(ServerEndpoint);
_serverSocket.Listen(int.MaxValue);

Exception Message

    #### Exception System.InvalidOperationException - CLR_E_INVALID_OPERATION (6) ####
    #### Message: 
    #### GHIElectronics.TinyCLR.Devices.Network.Provider.NetworkControllerApiWrapper::Bind [IP: 0000] ####
    #### System.Net.Sockets.Socket::Bind [IP: 001a] ####
    #### Charge_Control.MainApp::EthernetConnectionEstablished [IP: 002a] ####
    #### GHI_Framework.EthernetController::NetworkConnectionChanged [IP: 00cb] ####
    #### GHIElectronics.TinyCLR.Devices.Network.NetworkController::OnNetworkAddressChanged [IP: 000e] ####
    #### GHIElectronics.TinyCLR.Devices.Network.Provider.NetworkControllerApiWrapper::<.ctor>b__8_1 [IP: 001f] ####
Exception thrown: 'System.InvalidOperationException' in GHIElectronics.TinyCLR.Devices.Network.dll
An unhandled exception of type 'System.InvalidOperationException' occurred in GHIElectronics.TinyCLR.Devices.Network.dll

However! If I add a ReuseAddress socket option before calling the .Bind() method, the exception does not trigger:

Code Does Not Throw Exception

IPEndPoint ServerEndpoint = new IPEndPoint(EthernetController.IpAddress, tcpPort);
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_serverSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_serverSocket.Bind(ServerEndpoint);
_serverSocket.Listen(int.MaxValue);

So, is this the intended way this is supposed to work? And if so, does enabling this ReuseAddress option cause any known issues I should be aware of?

I’m adding a link to a previous post with a similar issue here:
Previous Post

I noticed you didn’t include a complete example. That makes it hard for others to understand the issue, find a bug in your code, or suggest improvements.

However, I think I can help you figure it out. The clue you gave says it works once and then needs a ‘resuseaddress’ option. Let’s think about what that could mean and see if we can solve the problem.

I know it sounds like a silly question, but I guess a better way to phrase it is why would a socket default to throwing an exception when reopening a server socket? Is it bad practice to close and reopen sockets or something? I was just hoping to get insight in what others normally do (and also bring some light if others might be seeing the same thing).

It is probable that the internal resources of the socket are not fully released upon closing. Consequently, it is imperative to “reuse” the socket the second time.

Firstly, verify whether the socket possesses a Dispose() method. If it does, utilize it immediately after the close, and then make sure all references to the socket are nulled.

In certain instances, it may be necessary for garbage collection to take place before all resources are released. You can explicitly initiate GC.

I believe you are trying to restart a listening socket if the network cable is disconnected. I would check to see if that is really necessary. I think the listen might stay active, and will work after the cable is reconnected. In the IPEndPoint I suggest that you use IPAddress.Any to avoid association with a specific interface.

Once again, if you provide a comprehensive example illustrating the issue, we can offer specific recommendations.