Revils
Revils

Reputation: 1508

Socket reuse not working

I have got the following two functions to start and stop a 'local server' (Socket listener).

public String startServer(Int32 port, Int32 maximumPendingConnections, ref String errorMsg) {
    try {
        // Creates one SocketPermission object for access restrictions
        permission = new SocketPermission(
        NetworkAccess.Accept,     // Allowed to accept connections 
        TransportType.Tcp,        // Defines transport types 
        "",                       // The IP addresses of local host 
        SocketPermission.AllPorts // Specifies all ports 
        );
        // Listening Socket object 
        sListener = null;
        // Ensures the code to have permission to access a Socket 
        permission.Demand();
        // Resolves a host name to an IPHostEntry instance 
        IPHostEntry ipHost = Dns.GetHostEntry("");
        // Gets first IP address associated with a localhost 
        ipAddr = ipHost.AddressList[0];
        // Creates a network endpoint 
        ipEndPoint = new IPEndPoint(ipAddr, port);
        // Create one Socket object to listen the incoming connection 
        sListener = new Socket(
            ipAddr.AddressFamily,
            SocketType.Stream,
            ProtocolType.Tcp
            );
        // Associates a Socket with a local endpoint 
        sListener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); //newly added as an answer
        sListener.Bind(ipEndPoint);
        sListener.Listen(maximumPendingConnections);

        // Begins an asynchronous operation to accept an attempt 
        AsyncCallback aCallback = new AsyncCallback(AcceptCallback);
        sListener.BeginAccept(aCallback, sListener);
    } catch (Exception e) {
        //ErrorHandling
    }
    return ipAddr.ToString();
}

Stop Connection:

public void stopServer(ref String errorMsg) {
    try {
        sListener.Shutdown(SocketShutdown.Both);
        sListener.Disconnect(true);
        sListener.Close();
        sListener.Dispose();
    } catch (Exception e) {
        //Errorhandling
    }
}

I have found on SO that you cannot reuse a socket, however if you set sListener.Disconnect(true); it should be able to reuse it. Besides I'm creating a new socket every time on starting. What am I missing here?

It gives the error back that every socket can only be used once. It gives an error on sListener.Bind(ipEndPoint);

@Edit 14:41 - 16-12-2015 I have found that if I add the following line of code before the sListener.Bind(ipEndPoint); It works;

sListener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

Upvotes: 0

Views: 508

Answers (2)

Andrey Nasonov
Andrey Nasonov

Reputation: 2629

The Connected property will always return false because socket is in listening state, not connected. Unfortunately, is not possible to "unlisten" the socket so you have to close it and create new socket.

Another issue is: the sequence Shutdown, Disconnect, Close and Dispose looks like kicking the dead body.

Upvotes: 1

u354356007
u354356007

Reputation: 3215

If you want to actually to reuse the socket, don't do Shutdown, Close and Dispose, since these calls return the resources used by the socket to the OS. Basically, your socket handler becomes invalid and the work done by Disconnect(true) is futile then.

(You also don't need to do Shutdown and Close at the same time. Just Close will do the trick.)

Upvotes: 1

Related Questions