寫一個客戶機/服務器程序和以前使用的電話是這樣的:試圖使代碼異步,但沒有阻止我的程序跑掉了?
TcpListener.AcceptTcpClient()
NetworkStream.Read()
NetworkStream.Write()
TcpListener.AcceptTcpClient()
工作正常,因爲在建立連接後的回調函數只調用。
但是,BeginRead()
也不能正常工作。出於某種原因,即使沒有數據發送,它也會執行並繼續通過。不知道發生了什麼。 NetworkStream.Read()
擋住了就好了,但這不是..
這裏是每當建立連接時創建的非工作線程:
private void HandleClientCommunication(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
try
{
byte[] header = new byte[4];
clientStream.BeginRead(header, 0, header.Length, Read, new StateData(clientStream, header)); // Runs even if no data is sent
int dataLength = BitConverter.ToInt32(header, 0); // Continues to this, even if no packets are sent..
byte[] data = new byte[dataLength]; // dataLength is 0 still of course because none of the code is blocking
clientStream.BeginRead(data, 0, dataLength, Read, new StateData(clientStream, data));
}
catch (IOException e)
{
Console.WriteLine(e.InnerException.Message);
}
// not relevant past here
}
這裏的讀法了。不知道是否它是需要弄清楚的問題,但我會將它不分:
private void Read(IAsyncResult async)
{
StateData stateData = (StateData)async.AsyncState;
stateData.BytesRead += stateData.Stream.EndRead(async);
if (stateData.BytesRead < stateData.Bytes.Length)
{
stateData.Stream.BeginRead(stateData.Bytes, 0, stateData.Bytes.Length, Read, stateData);
}
else
{
string message = Encoding.ASCII.GetString(stateData.Bytes);
Console.WriteLine(message);
}
}
所以,是的,我只是試圖建立與異步調用的客戶機服務器交互,並有每一個「包」包括:頭部的數據長度爲int,然後是數據本身。不幸的是,事情似乎沒有奏效,我不確定問題是什麼。
好像我必須包括一些手動形式的阻止,但不會打敗使用異步調用的目的?那麼爲什麼不回到那個普通的同步阻止呼叫,如Read()
和AcceptTcpClient()
那麼呢?
我不認爲我在這裏是完全理解的東西..
感謝您的回覆。看起來好像即使沒有讀取任何內容,回調仍在執行。 BeginRead的回調在與*明顯*無數據連接時執行。不知道如何繼續.. –
@加布裏埃爾:這可能是因爲你發出第二個BeginRead調用要求0字節的數據。這可能是即時執行的那個* call的回調。無論如何,你真的不應該再次調用'BeginRead'直到第一次讀取完成。 –
你解釋得很好..我想我會去買你的書..大聲笑 –