以下のコードは、サーバーからのデータがそれほど多くない場合、またはデータが多くて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(); }
}