0

シンプルな機能のエコー ソケット クライアント/サーバーをコーディングしようとしています。クライアントを使用して同期サーバーを動作させることができましたが、今は非同期サーバーが必要です。

Microsoft のバージョンを使用している場合、正常に機能しています。ASyncサーバー:

https://msdn.microsoft.com/en-us/library/fx6588te(v=vs.110).aspx

Microsoft 非同期クライアント:

https://msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx

私が今試みているのは、Microsoft Async ClientをLinux C++ Overlapped I/O Serverと通信させることです:

http://www.tutorialized.com/tutorial/Linux-C-Overlapped-Server-and-Client-Socket-Example/77220

ここで問題が始まります。接続が確立され、サーバーにメッセージを送信できます。サーバーはメッセージをエコー バックして応答しますが (デバッグおよびターミナル出力に従って)、Microsoft ASync クライアントはソケットで応答を取得しません。

非同期クライアントを重複 I/O サーバーに接続することは不可能ですか? サーバーからの応答がクライアントに届かない理由がわかりません。Microsoft ASync クライアントをデバッグすると、Receive次のコード行が関数に渡されないことがわかります。

receiveDone.WaitOne();

receiveDone は ManualResetEvent です。

private static ManualResetEvent receiveDone =
            new ManualResetEvent(false);

環境:

// Receive the response from the remote device.
Receive(client);
receiveDone.WaitOne();

これは受信用のコールバック関数で、完了したら receiveDone を設定します。bytesRead0 を超えることはありません。:

private void ReceiveCallback(IAsyncResult ar)
{
    try
    {
        // Retrieve the state object and the client socket 
        // from the asynchronous state object.
        StateObject state = (StateObject)ar.AsyncState;
        Socket client = state.workSocket;

        // Read data from the remote device.
        int bytesRead = client.EndReceive(ar);

        if (bytesRead > 0)
        {
            // There might be more data, so store the data received so far.
            state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

            // Get the rest of the data.
            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReceiveCallback), state);
        }
        else
        {
            // All the data has arrived; put it in response.
            if (state.sb.Length > 1)
            {
                response = state.sb.ToString();
            }
            // Signal that all bytes have been received.
            receiveDone.Set();
        }
    }
    catch (Exception e)
    {
        msg("Fail ReceiveCallback: " + e.Message, false);
    }
} 

とにかく、このコードは ASync サーバーに接続されているときに機能しますが、オーバーラップ I/O サーバーには接続されていません。そのため、実際には、オーバーラップ I/O サーバー コードで何を変更すればよいかを尋ねています。受けられる?

これは、Hello WorldASync クライアントから送信された場合のサーバーからの出力です。

root@deb7sve:/home/petlar/Host/SockServer# g++ OverlappedServer.cpp -o os.out -lpthread
root@deb7sve:/home/petlar/Host/SockServer# ./os.out
---------------------
Received connection from 10.0.2.2
Read 13 bytes from 4
Sent 13 bytes to 4
4

1 に答える 1

1

そのクライアント コードは、接続がシャットダウンされたときにのみイベントを設定します。あなたのコメントによると、サーバーは接続を閉じません。そのため、イベントが設定されることはありません。

クライアント コードを破棄し、単純な同期コードを使用して書き直します。コードの 50% は非同期 IO の作成に費やされています (壊れた方法で)。Async IO は、ネットワーク効率を改善することではありません。スレッドリソースを節約するためにあります。クライアントでは必要ない可能性があります。

于 2015-04-19T14:05:03.127 に答える