這篇文章我們將前進一大步,使用異步的方式來對服務端編程,以使它成為一個真正意義上的服務器 :可以為多個客戶端的多次請求服務。但是開始之前,我們需要解決上一節中遺留的一個問題。
消息發送時的問題
這個問題就是:客戶端分兩次向流中寫入數據(比如字符串)時,我們主觀上將這兩次寫入視為兩次 請求;然而服務端有可能將這兩次合起來視為一條請求,這在兩個請求間隔時間比較短的情況下尤其如此 。同樣,也有可能客戶端發出一條請求,但是服務端將其視為兩條請求處理。下面列出了可能的情況,假 設我們在客戶端連續發送兩條“Welcome to Tracefact.Net!”,則數據到達服務端時可能有這樣三種情 況:
NOTE:在這裡我們假設采用ASCII編碼方式,因為此時上面的一個方框正好代表一個字節,而字符串到 達末尾後為持續的0(因為byte是值類型,且最小為0)。
上面的第一種情況是最理想的情況,此時兩條消息被視為兩個獨立請求由服務端完整地接收。第二種 情況的示意圖如下,此時一條消息被當作兩條消息接收了:
而對於第三種情況,則是兩條消息被合並成了一條接收:
如果你下載了上一篇文章所附帶的源碼,那麼將ClIEnt2.cs進行一下修改,不通過用戶輸入,而是使 用一個for循環連續的發送三個請求過去,這樣會使請求的間隔時間更短,下面是關鍵代碼:
string msg = "Welcome to TraceFact.Net!";
for (int i = 0; i <= 2; i++) {
byte[] buffer = Encoding.Unicode.GetBytes(msg); // 獲得緩存
try {
streamToServer.Write(buffer, 0, buffer.Length); // 發往服務器
Console.WriteLine("Sent: {0}", msg);
} catch (Exception ex) {
Console.WriteLine(ex.Message);
break;
}
}
運行服務端,然後再運行這個客戶端,你可能會看到這樣的結果: