在上次连接关闭后,如何通过套接字侦听传入连接?

时间:2013-02-28 17:33:40

标签: c# sockets listener

我正在设置一个套接字来监听传入的连接:

public Socket Handler;

public void StartListening()
{
    // Establish the locel endpoint for the socket
    IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, Port);

    // Create a TCP/IP socket
    Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    try
    {
        // Bind the socket to the local endpoint and listen
        listener.Blocking = false;
        listener.Bind(localEndPoint);
        listener.Listen(100);

        // Start an asynchronous socket to listen for connections
        listener.BeginAccept( new AsyncCallback(AcceptCallback), listener);
    }
    catch (Exception e)
    {
        invokeStatusUpdate(0, e.Message);
    }            
}

private void AcceptCallback(IAsyncResult ar)
{
    // Get the socket that handles the client request
    Socket listener = (Socket) ar.AsyncState;
    Socket handler = listener.EndAccept(ar);
    Handler = handler;

    // Create the state object
    StateObject state = new StateObject();
    state.workSocket = handler;
    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}

如上所示,一旦建立连接,我就设置了BeginReceive回调。这很好。

最终我想要关闭当前连接,然后再次开始侦听我的套接字以进行连接尝试:

public void CloseNode(bool restart)
{
    try
    {
        if (Handler != null)
        {
            Handler.Shutdown(SocketShutdown.Both);
            Handler.Close();
            Handler.Dispose();
            Handler = null;
        }

        if (restart)
            StartListening();
    }
    catch (Exception e)
    {
        invokeStatusUpdate(0, e.Message);
    }
}

我的close方法采用布尔值来知道是否应该开始侦听更多的传入连接。

问题是,当我回到我的StartListening方法时,我在行listener.Bind(localEndPoint);上遇到一个例外,说“每个套接字地址只有一个用法(协议/网络地址) / port)通常允许“

如何设置我的听力以便再次开始收听?

1 个答案:

答案 0 :(得分:1)

将其分为两种方法:startListening()continueListening()

开始收听将初始化所有内容,然后呼叫继续收听。你现在打电话的地方现在就开始聆听,而是打电话继续听。

或者,如果您想一次允许多个,只需将BeginAccept调用放入while(true)循环即可。这将永远接受所有传入连接,即使其他人已连接。这就是为什么它毕竟是异步的!

这是你的成员变量

public Socket Handler;
private socket listener; // added by corsiKa

这是您的新启动方法

public void StartListening()
{
    // Establish the locel endpoint for the socket
    IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, Port);

    // Create a TCP/IP socket
    listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    try
    {
        // Bind the socket to the local endpoint and listen
        listener.Blocking = false;
        listener.Bind(localEndPoint);
        listener.Listen(100);

        // Start an asynchronous socket to listen for connections
        performListen(listener); // changed by corsiKa
    }
    catch (Exception e)
    {
        invokeStatusUpdate(0, e.Message);
    }            
}

这是你的执行听力方法

// added by corsiKa
private void performListen(Socket listener) {
    listener.BeginAccept( new AsyncCallback(AcceptCallback), listener);
}

这是你的新近距离方法

// variable name changed by corsiKa
public void CloseNode(bool acceptMoreConnections)
{
    try
    {
        if (Handler != null)
        {
            Handler.Shutdown(SocketShutdown.Both);
            Handler.Close();
            Handler.Dispose();
            Handler = null;
        }
        // changed by corsiKa
        if (acceptMoreConnections)
            performListen(listener);
    }
    catch (Exception e)
    {
        invokeStatusUpdate(0, e.Message);
    }
}