1

着信接続をリッスンするソケットを設定しています。

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 メソッドは、さらに着信接続のリッスンを開始する必要があるかどうかを知るためにブール値を取ります。

問題は、メソッドに戻ると、 「通常、各ソケット アドレス (プロトコル/ネットワーク アドレス/ポート) の使用は 1 つだけ許可されている」というStartListening行で例外が発生することです。listener.Bind(localEndPoint);

リスニングを再開するにはどうすればよいですか?

4

1 に答える 1

2

2 つの方法に分割します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);
    }
}
于 2013-02-28T17:36:10.140 に答える