1

.NET C#、マルチスレッド ソケット アプリケーションに問題があります。

ランダムにしばらくすると、コールバック関数を実行せずに接続が受け入れられ、受け入れられなくなります。

リスナーとコールバック関数のコードは次のとおりです。

    public void StartListening()
    {
        // Data buffer for incoming data.
        byte[] bytes = new Byte[1024];

        // Establish the local endpoint for the socket.
        // The DNS name of the computer
        // running the listener is "host.contoso.com".
        IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, listenPort);//Listen on all available network interfaces

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

        // Bind the socket to the local endpoint and listen for incoming connections.
        bool signal = true;
        try
        {
            listener.Bind(localEndPoint);       
            listener.Listen(listenPort);

            while (startlisten)
            {
                // Set the event to nonsignaled state.
                allDone.Reset();
                if (signal)
                {
                    // Start an asynchronous socket to listen for connections.
                    string s = string.Format("Server Socket: Waiting for a connection at Port:{0}", listenPort);
                    DisplayMsg(s);
                    listener.BeginAccept(
                        new AsyncCallback(AcceptCallback),
                        listener);
                }
                // Wait until a connection is made before continuing.
                signal = allDone.WaitOne(100);
            }
            listener.Close();
        }
        catch (Exception e)
        {
            if (e is System.Net.Sockets.SocketException)
            {
                SocketException socex = (e as SocketException);

                throw new Exception(socex.Message);
            }
            else
            {
                throw new Exception(e.Message);
            }
        }
    }

    public void AcceptCallback(IAsyncResult ar)
    {
        // Signal the main thread to continue.

        try
        {
            if (startlisten)
            {
                // Get the socket that handles the client request.
                Socket listener = (Socket)ar.AsyncState;

                TCPClient tcp = frm.GetClientObj();
                tcp.socketForServer = listener.EndAccept(ar);

                DisplayErrorMsg("Connection Request From: " + tcp.socketForServer.RemoteEndPoint.ToString());

                tcp.Connected = true;
                tcp.ReceiveData();

                // Create the state object.
                //                StateObject state = new StateObject();
                //                state.workSocket = handler;
                //                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                //                    new AsyncCallback(ReadCallback), state);
            }
        }
        catch (Exception e)
        {
            if (e is System.Net.Sockets.SocketException)
            {
                SocketException socex = (e as SocketException);

                DisplayErrorMsg(socex.Message);
            }
            else
            {
                DisplayErrorMsg(e.Message);
            }
        }
        allDone.Set();

    }
4

2 に答える 2

1

これは、EndAccept の前にリスニング ソケットを閉じた場合に発生します

「BeginAccept メソッドへの保留中の呼び出しをキャンセルするには、Socket を閉じます。非同期操作の進行中に Close メソッドが呼び出されると、BeginAccept メソッドに提供されたコールバックが呼び出されます。EndAccept メソッドへの後続の呼び出しは、ObjectDisposedException をスローします。操作がキャンセルされたことを示します。」

http://msdn.microsoft.com/en-us/library/5bb431f9.aspx

于 2013-07-26T13:27:47.420 に答える
0

答えが見つかりました。それはallDoneイベントに関連していて、if ループ内で通知する必要があります。

if (signal)
{
    allDone.Reset();
    // Start an asynchronous socket to listen for connections.
    string s = string.Format("Server Socket: Waiting for a connection at Port:{0}", listenPort);
    DisplayMsg(s);
    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
}

// Wait until a connection is made before continuing.
signal = allDone.WaitOne(100);
于 2016-07-13T13:53:52.277 に答える