我是新來的異步套接字編程,我有我的異步函數的問題。TcpListener和TcpClient的異步函數問題,函數沒有等待關鍵字
我正在嘗試創建一個使用Windows窗體作爲客戶端和服務器的控制檯應用程序的聊天程序。
這裏是處理我的服務器上的連接代碼:
public async void StartServer()
{
TcpListener listener = new TcpListener(_ip, _port);
listener.Start();
Console.WriteLine("Server is running on IP: {0} Port: {1}", _ip.ToString(), _port);
while (true)
{
try
{
TcpClient client = await listener.AcceptTcpClientAsync();
HandleConnections(client);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
private async void HandleConnections(TcpClient client)
{
NetworkStream stream = client.GetStream();
byte[] buffer = new byte[256];
string message = null;
int x;
while(stream.DataAvailable)
{
x = await stream.ReadAsync(buffer, 0, buffer.Length);
message += Encoding.ASCII.GetString(buffer);
}
message = message.Replace('\0', ' ');
message = message.Trim();
Console.WriteLine("Message Recieved: " + message);
byte[] bytes = Encoding.ASCII.GetBytes(message);
await stream.WriteAsync(bytes, 0, bytes.Length);
stream.Close();
}
這裏是連接到服務器的客戶端程序代碼:
private async void ConnectButton_Click(object sender, EventArgs e)
{
IPAddress address = IPAddress.Parse(IPInput.Text);
client = new TcpClient();
await client.ConnectAsync(address, 12345);
NetworkStream stream = client.GetStream();
string message = UsernameInput.Text + " Connected!";
Task<int> sendTask = SendMessage(stream, message);
int sendComp = await sendTask;
Task<string> recieveTask = RecieveMessage(stream);
string recieved = await recieveTask;
stream.Close();
ChatText.AppendText(recieved);
}
private async Task<int> SendMessage(NetworkStream stream, string message)
{
byte[] bytes = Encoding.ASCII.GetBytes(message + "\r\n");
await stream.WriteAsync(bytes, 0, bytes.Length);
return 1;
}
private async Task<string> RecieveMessage(NetworkStream stream)
{
byte[] buffer = new byte[256];
string message = null;
int x;
while (stream.DataAvailable)
{
x = await stream.ReadAsync(buffer, 0, buffer.Length);
message += Encoding.ASCII.GetString(buffer);
}
return message;
}
的第一個問題,我有是當我運行客戶端程序並單擊ConnectButton時,該消息被髮送到輸出Message Recieved: user Connected!
的服務器程序,但隨後客戶端程序在行ChatText.AppendText(recieved);
上遇到空引用異常,說recieved
變量爲空。看起來線string recieved = await recieveTask;
沒有等待任務完成執行,並且它跳到下一行,沒有給recieved
賦值。如果我在private async Task<string> RecieveMessage(NetworkStream stream)
函數的頂部放置了一個斷點並逐步完成,那麼recieved
變量會得到它的值,並且代碼將成功完成,但是沒有斷點,我會得到空引用異常。
我遇到的下一個問題是,如果我讓服務器繼續運行並再次打開客戶端並嘗試連接,服務器會在行message = message.Replace('\0', ' ');
上收到空引用異常。我第一次使用客戶端運行時,服務器成功接收到消息,但是第二次,它沒有從流中獲取任何數據並將變量保留爲null,從而導致空引用異常。
我很抱歉,如果我的代碼是垃圾,我一直在閱讀MSDN文檔幾個小時,我無法想出一個解決方案,我覺得我這樣做是完全錯誤的。所以我的問題如下:
是什麼導致我遇到這些錯誤?我以正確的方式處理這個問題嗎?
哇,我沒有想到像改變我的while循環一樣簡單的事情可以解決這個問題。非常感謝。我現在覺得有點愚蠢,因爲我被這個問題困住了多久。 – PhantomWhiskers
@PhantomWhiskers - 一個單獨的問題,它即將咬你 - 你真的*需要注意'ReadAsync'返回的*值。它會告訴你*已收到多少個字節。你的很多代碼似乎都假定你會收到與你所要求的字節數完全一樣多的字節,這並不能保證。請記住,TCP的抽象是一個字節流,而不是*消息*。如果你想發送和接收消息,那麼你需要在TCP上實現它,或者轉移到更高層次的抽象。 –