1

C# winsock クラスを使用してクライアント/サーバー プログラムを作成しています。マルチスレッド サーバー (クライアント接続ごとに 1 スレッド) は、データの小さなチャンクをクライアントに送信します。パフォーマンス上の理由から、Send の代わりに BeginSend を使用しようとしています。うまくいっているようです。私が遭遇している唯一の問題は、数時間ごとに BeginSend がデータの送信を停止し、クライアントが再接続してさらにデータを受信する必要があることです。そのため、サーバーに EndSend コールバックを追加しようとしましたが、問題はまだ残っています。クライアント側では、BeginReceive の代わりに Receive のみを使用しており、サーバー コードではセマフォを使用していません。コードは非常に簡単です。私が気づいたことの 1 つは、サーバー上にアイドル状態のクライアント接続があるように見えることです。デッドロックが原因ではないかと考えています。なぜこれがそうなのか、誰にも分かりますか?どうもありがとう!

実際に送信したコードは次のとおりです。

    protected virtual void SendMessage(Socket socket, byte[] message)
    {
        try 
        {
            if (socket.Connected)
            {
                _StateObject state = new _StateObject();

                state.socket = socket;
                state.nBytes = message.Length;

                socket.BeginSend(message, 0, message.Length, SocketFlags.None, new AsyncCallback(SendCallback), state);
            }
        }
        catch (Exception ex)
        {
            SocketErrorEventArgs e = new SocketErrorEventArgs();
            e.ex = ex;
            if (SocketBeginSendError != null) SocketBeginSendError(null, e);
        }
    }

    protected virtual void SendCallback(IAsyncResult ar)
    {
        try
        {
            _StateObject state = (_StateObject)ar.AsyncState;
            Socket s = state.socket;

            int nBytesActuallySent = s.EndSend(ar);

            if (nBytesActuallySent != state.nBytes)
            {
                SocketErrorEventArgs e = new SocketErrorEventArgs();
                e.nBytes1 = state.nBytes;
                e.nBytes2 = nBytesActuallySent;
                if (SocketIncompleteSendError != null) SocketIncompleteSendError(null, e);
            }

        }
        catch (Exception ex)
        {
            SocketErrorEventArgs e = new SocketErrorEventArgs();
            e.ex = ex;
            if (SocketEndSendError != null) SocketEndSendError(null, e);
        }
    }
4

0 に答える 0