2

以下のコードは、サーバーからのデータがそれほど多くない場合、またはデータが多くてThread.Sleep(500)行のコメントを外した場合に機能します。ただし、この行は使用したくありませんThread.Sleepが、削除すると、サーバーからすべてのデータを読み取る前にプログラムが終了します。問題は、EndRead()すべてのデータが読み取られるまでブロックされないことです。これは理解でき、 への再帰呼び出しで修正する必要がありますが、ReceiveCallbackそうではありません。

Linux で C/C++ を使用して作成されたクライアントが動作しています。私はそれを c# と .Net で動作させようとしています。Linux で .Net 4.0 で MonoDevelop を使用しています。これを修正する方法についての助けに感謝します。

cli.send("command");
// Thread.Sleep(500); 
cli.receive();
Console.WriteLine("response: {0}", cli.Response);
    private Static ManualResetEvent recvEvt = new ManualResetEvent(false);

    public static void receive() {
        StateObject state = new StateObject();
        try {
            state.stream = client.GetStream();
            state.stream.BeginRead(state.buffer, 0, state.bufferSize, new AsyncCallback(ReceiveCallback), state);
            recvEvt.WaitOne();
            recvEvt.Reset();
        }
        catch (ArgumentNullException ne) { errorMessage = ne.ToString(); }
        catch (ArgumentException ae) { errorMessage = ae.ToString(); }
        catch (ObjectDisposedException oe) { errorMessage = oe.ToString(); }
        catch (InvalidOperationException ie) { errorMessage = ie.ToString(); }
        catch (SocketException se) { errorMessage = se.ToString(); }
    }


   private static void ReceiveCallback(IAsyncResult ar) {
        StateObject state = (StateObject)ar.AsyncState;
        try {
            int bytesRead = state.stream.EndRead(ar);
            if (bytesRead > 0 ) {
                state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
                response = state.sb.ToString();
                if (state.stream.DataAvailable) {
                    state.stream.BeginRead(state.buffer, 0, state.bufferSize, new AsyncCallback(ReceiveCallback), state);
                    recvEvt.WaitOne();
                    recvEvt.Reset();
                }else
                    recvEvt.Set();
            }else
                recvEvt.Set();
        }
        catch (ArgumentNullException ne) { errorMessage = ne.ToString(); }
        catch (ArgumentException ae) { errorMessage = ae.ToString(); }
        catch (ObjectDisposedException oe) { errorMessage = oe.ToString(); }
        catch (InvalidOperationException ie) { errorMessage = ie.ToString(); }
        catch (SocketException se) { errorMessage = se.ToString(); }
    }
4

1 に答える 1