中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C#網絡編程消息發送問題舉例分析

發布時間:2021-12-03 10:00:17 來源:億速云 閱讀:193 作者:iii 欄目:編程語言

本篇內容介紹了“C#網絡編程消息發送問題舉例分析”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

C#網絡編程消息發送問題:客戶端分兩次向流中寫入數據(比如字符串)時,我們主觀上將這兩次寫入視為兩次請求;然而服務端有可能將這兩次合起來視為一條請求,這在兩個請求間隔時間比較短的情況下尤其如此。同樣,也有可能客戶端發出一條請求,但是服務端將其視為兩條請求處理。下面列出了可能的情況,假設我們在客戶端連續發送兩條“Welcome to Tracefact.net!”,則數據到達服務端時可能有這樣三種情況:

C#網絡編程消息發送問題舉例分析

NOTE:在這里我們假設采用ASCII編碼方式,因為此時上面的一個方框正好代表一個字節,而字符串到達末尾后為持續的0(因為byte是值類型,且最小為0)。

上面的***種情況是最理想的情況,此時兩條消息被視為兩個獨立請求由服務端完整地接收。第二種情況的示意圖如下,此時一條消息被當作兩條消息接收了:

C#網絡編程消息發送問題舉例分析

而對于第三種情況,則是兩條消息被合并成了一條接收:

C#網絡編程消息發送問題舉例分析

如果你下載了上一篇文章所附帶的源碼,那么將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;  }  }

C#網絡編程之運行服務端,然后再運行這個客戶端,你可能會看到這樣的結果:

C#網絡編程消息發送問題舉例分析

C#網絡編程消息發送問題舉例分析

可以看到,盡管上面將消息分成了三條單獨發送,但是服務端卻將后兩條合并成了一條。對于這些情況,我們可以這樣處理:就好像HTTP協議一樣,在實際的請求和應答內容之前包含了HTTP頭,其中是一些與請求相關的信息。我們也可以訂立自己的協議,來解決這個問題,比如說,對于上面的情況,我們就可以定義這樣一個協議:

[length=XXX]:其中xxx是實際發送的字符串長度(注意不是字節數組buffer的長度),那么對于上面的請求,則我們發送的數據為:“[length=25]Welcome to TraceFact.Net!”。而服務端接收字符串之后,首先讀取這個“元數據”的內容,然后再根據“元數據”內容來讀取實際的數據,它可能有下面這樣兩種情況:

NOTE:我覺得這里借用“元數據”這個術語還算比較恰當,因為“元數據”就是用來描述數據的數據。

“[“”]”中括號是完整的,可以讀取到length的字節數。然后根據這個數值與后面的字符串長度相比,如果相等,則說明發來了一條完整信息;如果多了,那么說明接收的字節數多了,取出合適的長度,并將剩余的進行緩存;如果少了,說明接收的不夠,那么將收到的進行一個緩存,等待下次請求,然后將兩條合并。
“[”“]”中括號本身就不完整,此時讀不到length的值,因為中括號里的內容被截斷了,那么將讀到的數據進行緩存,等待讀取下次發送來的數據,然后將兩次合并之后再按上面的方式進行處理。
接下來我們來看下如何來進行實際的操作,實際上,這個問題已經不屬于C#網絡編程的內容了,而完全是對字符串的處理。所以我們不再編寫服務端/客戶端代碼,直接編寫處理這幾種情況的方法:

public class RequestHandler {  private string temp = string.Empty;   public string[] GetActualString(string input) {  return GetActualString(input, null);  }   private string[] GetActualString(  string input, List<string> outputList) {  if (outputList == null)  outputList = new List<string>();   if (!String.IsNullOrEmpty(temp))  input = temp + input;   //C#網絡編程string output = "";  string pattern = @"(?<=^\[length=)(\d+)(?=\])";  int length;   if (Regex.IsMatch(input, pattern)) {   Match m = Regex.Match(input, pattern);   // 獲取消息字符串實際應有的長度  length = Convert.ToInt32(m.Groups[0].Value);   // 獲取需要進行截取的位置  int startIndex = input.IndexOf(']') + 1;   // 獲取從此位置開始后所有字符的長度  output = input.Substring(startIndex);   if (output.Length == length) {  // 如果output的長度與消息字符串的應有長度相等  // 說明剛好是完整的一條信息  outputList.Add(output);  temp = "";  } else if (output.Length < length) {  // 如果之后的長度小于應有的長度,  // 說明沒有發完整,則應將整條信息,包括元數據,全部緩存  // 與下一條數據合并起來再進行處理  temp = input;  // 此時程序應該退出,因為需要等待下一條數據到來才能繼續處理   } else if (output.Length > length) {  // 如果之后的長度大于應有的長度,  // 說明消息發完整了,但是有多余的數據  // 多余的數據可能是截斷消息,也可能是多條完整消息   // 截取字符串  output = output.Substring(0, length);  outputList.Add(output);  temp = "";   // 縮短input的長度  input = input.Substring(startIndex + length);   // 遞歸調用  C#網絡編程GetActualString(input, outputList);  }  } else {// 說明“[”,“]”就不完整  temp = input;  }   return outputList.ToArray();  }  }

這個方法接收一個滿足協議格式要求的輸入字符串,然后返回一個數組,這是因為如果出現多次請求合并成一個發送過來的情況,那么就將它們全部返回。隨后簡單起見,我在這個類中添加了一個靜態的Test()方法和PrintOutput()幫助方法,進行了一個簡單的測試,注意我直接輸入了length=13,這個是我提前計算好的。

public static void Test() {  RequestHandler handler = new RequestHandler();  string input;   // ***種情況測試 - 一條消息完整發送  input = "[length=13]明天中秋,祝大家節日快樂!";  handler.PrintOutput(input);   // 第二種情況測試 - 兩條完整消息一次發送  input = "明天中秋,祝大家節日快樂!";  input = String.Format  ("[length=13]{0}[length=13]{0}", input);  handler.PrintOutput(input);   // 第三種情況測試A - 兩條消息不完整發送  input = "[length=13]明天中秋,祝大家節日快樂![length=13]明天中秋";  handler.PrintOutput(input);   input = ",祝大家節日快樂!";  handler.PrintOutput(input);   //C#網絡編程// 第三種情況測試B - 兩條消息不完整發送  input = "[length=13]明天中秋,祝大家";  handler.PrintOutput(input);   input = "節日快樂![length=13]明天中秋,祝大家節日快樂!";  handler.PrintOutput(input);   //C#網絡編程 // 第四種情況測試 - 元數據不完整  input = "[leng";  handler.PrintOutput(input); // 不會有輸出   input = "th=13]明天中秋,祝大家節日快樂!";  handler.PrintOutput(input);   }   // 用于測試輸出  private void PrintOutput(string input) {  Console.WriteLine(input);  string[] outputArray = GetActualString(input);  foreach (string output in outputArray) {  Console.WriteLine(output);  }  Console.WriteLine();  }

C#網絡編程運行上面的程序,可以得到如下的輸出:

C#網絡編程消息發送問題舉例分析

“C#網絡編程消息發送問題舉例分析”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

紫云| 尚志市| 铁岭县| 青铜峡市| 洛隆县| 鄱阳县| 兴山县| 中牟县| 资源县| 通州市| 舞阳县| 大丰市| 土默特右旗| 云林县| 威远县| 高淳县| 新河县| 温宿县| 江津市| 宜黄县| 丽江市| 叙永县| 吉首市| 灵寿县| 云霄县| 阿城市| 恩平市| 云龙县| 桃园县| 屯门区| 靖远县| 岢岚县| 宿州市| 合水县| 尖扎县| 揭阳市| 宿迁市| 焉耆| 比如县| 榕江县| 丰原市|