標籤:通訊 tcp cross sock 規範 編碼 add window static
協議種類
開發Socket程式有兩種協議類型,一種是用文本描述的,類似HTTP協議,定義字元集,好處是相容性和調試方便,缺點是解析文本會損耗一些效能;一種是用Code加結構體,定義位元組順序,好處是效能高,缺點是相容性和調試不方便。這個可以根據應用情境靈活選擇,如果您的應用相對穩定,需求變化少,效能要求高,則可以使用Code加結構體的方式。如果您的應用需要不停的擴充功能,但是對效能要求不苛刻,則可以使用文本解析的方式。這兩種協議有兩個比較典型的應用情境,Code加結構體更多應用在中介軟體上,因為協議的封裝都是透明的,不需要聯調,而且效能要求較高;文本解析則更多應用在外部互動上,如和裝置、手機通訊,需要聯調,但是效能要求沒那麼高。
我們Demo是採用文本解析的方式,具體可以根據應用靈活選擇。
定義協議有以下注意點(方便不同平台接入)。
位元組順序
不同硬體平台或作業系統下,位元組順序是不一致的,有的是高位在前,低位在後,有的則是低位在前。Windows是低位在前,高位在後,每個平台下都有函數實現位元組轉換。TCP/IP定義的位元組順序是高位在前、低位在後,可以使用IPAddress類的
// // 摘要: // 將整數值由網路位元組順序轉換為主機位元組順序。 // // 參數: // network: // 以網路位元組順序表示的要轉換的數字。 // // 返回結果: // 以主機位元組順序表示的整數值。 [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static int NetworkToHostOrder(int network); // // 摘要: // 將長值由網路位元組順序轉換為主機位元組順序。 // // 參數: // network: // 以網路位元組順序表示的要轉換的數字。 // // 返回結果: // 以主機位元組順序表示的長值。 [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static long NetworkToHostOrder(long network); // // 摘要: // 將短值由網路位元組順序轉換為主機位元組順序。 // // 參數: // network: // 以網路位元組順序表示的要轉換的數字。 // // 返回結果: // 以主機位元組順序表示的短值。 [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public static short NetworkToHostOrder(short network);
來實現網路位元組順序轉為本地位元組順序,反之可以調用
// // 摘要: // 將整數值由主機位元組順序轉換為網路位元組順序。 // // 參數: // host: // 以主機位元組順序表示的要轉換的數字。 // // 返回結果: // 以網路位元組順序表示的整數值。 public static int HostToNetworkOrder(int host); // // 摘要: // 將長值由主機位元組順序轉換為網路位元組順序。 // // 參數: // host: // 以主機位元組順序表示的要轉換的數字。 // // 返回結果: // 以網路位元組順序表示的長值。 public static long HostToNetworkOrder(long host); // // 摘要: // 將短值由主機位元組順序轉換為網路位元組順序。 // // 參數: // host: // 以主機位元組順序表示的要轉換的數字。 // // 返回結果: // 以網路位元組順序表示的短值。 public static short HostToNetworkOrder(short host);
來實現本地位元組順序轉為網路位元組順序。
更流行的做法是使用網路位元組順序,這樣規範統一。我們這裡使用Windows位元組順序,即低位在前、高位在後,和網路位元組順序剛好相反。
字元集
字元集最合適的就是使用UTF-8,這個編碼是免費的,對於某些不支援中文的嵌入式系統,全英文可以不需要轉換就是UTF-8格式,對於跨平台具有優勢。
資料包格式
Code加結構體、文本解析兩種協議風格都是統一使用相同的資料包格式,即先發一個4位元組的長度,後面跟著是內容,下一個也是先發一個4位元組長度,接著是內容。結構體可以定義為檔案流結構體,採用位元組對齊。
協議樣本
Active:檢測串連(心跳包)
用戶端->伺服器 { [Request] Command=Active } 伺服器->用戶端 { [Response] Command= Active Code= Error Code#錯誤碼 Message=Message#如果出錯,返回錯誤描述資訊 }
C#高效能大容量SOCKET並發(八):通訊協議