套接字重用不起作用

时间:2015-12-16 09:42:55

标签: c# sockets

我有以下两个功能来启动和停止本地服务器' (套接字监听器)。

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();
}

停止连接:

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

我在SO上发现你不能重用套接字,但是如果你设置sListener.Disconnect(true);它应该能够重用它。除了我每次启动时都创建一个新的套接字。我在这里缺少什么?

它给出了错误,即每个套接字只能使用一次。它在sListener.Bind(ipEndPoint);

上出错

@Edit 14:41 - 16-12-2015 我发现如果我在sListener.Bind(ipEndPoint);它起作用之前添加以下代码行;

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

2 个答案:

答案 0 :(得分:1)

如果您想实际重用套接字,请不要执行ShutdownCloseDispose,因为这些调用会将套接字使用的资源返回给操作系统。基本上,您的套接字处理程序变得无效,Disconnect(true)完成的工作是徒劳的。

(您也不需要同时执行ShutdownClose。只需Close就行了。)

答案 1 :(得分:1)

Connected属性将始终返回false,因为套接字处于侦听状态,未连接。不幸的是,不可能" unlisten"套接字,所以你必须关闭它并创建新的套接字。

另一个问题是:序列ShutdownDisconnectCloseDispose看起来像是踢死了尸体。