我們知道,消息在網路上傳輸的是字節流,而我們主流的面向對象系統中處理的卻是 “ 對象 ” ,如何將從網絡上接收到的字節流轉化為 “ 對象 ” ,又如何將 “ 對象 ” 轉化為字節流以便通過網絡傳遞給其他系統,這便是 IContract 接口定義的內容:

2 /// IContract用于抽象通信協議格式的基礎接口。
3 /// </summary>
4 public interface IContract
5 {
6 void FillMyself( byte []data, int offset); // 將流解析為對象
7 int GetStreamLength();
8
9 byte []ToStream(); // 將對象轉化為流
10 void ToStream( byte []buff, int offset);
11 }
IContract
接口中的各個成員的意思非常的清楚,含有
offset
參數的重載
ToStream
方法(第
10
行)可以將轉化的結果流寫到指定的
buff
中,這個方法是必須的,否則就會遇到很多需要拷貝緩沖區的操作,這將嚴重的損害運行的效率。
很多朋友一定想到了,
.NET
中將對象轉化為字節流或將流轉化為對象的最方便的方式就是使用
“
序列化
”
,是的,如果各個通信的系統都是基于
.NET
平臺創建的,當然沒有問題,這種情況下,使用
.NET Remoting
可能會更好(使用
Remoting
可以完全省略對消息協議的關心,因為
Remoting
已經幫你打點好了一切)。但是更多的情況是,相互通信的系統是異構的。比如,服務端是
.NET
平臺,而客戶端卻是
PDA
上
C++
寫的程序,遇到這種情形,
.NET
的序列化、
Remoting
就無能為力了,我們必須自己手動打理一切。你也許會說,可以使用
WebService
?呵呵,好了,
ESFramework
主要關注的是構建基于
Tcp
或
Udp
網絡系統,至于什么情況下,該使用
WebService
還是該直接在更低層的
TCP/UDP
上構建系統的問題,還是留待讀者自己去思考吧:)
如果不能使用
.NET
的
“
序列化
”
,那么常用的是什么方法來完成
“
字節流《=》消息對象
”
的轉換了,即
IContract.FillMyself
和
IContract.ToStream
的實現方式是什么?一個字節一個字節的處理。比如,我們消息協議中規定,接收到的字節流的前四個字節是一個使用
UTF8
編碼的字符串
“@@@@”
,那么,我們解析時,就用
UTF8
來將接收到的前
4
個字節解析為字符串
“@@@@”
。接下來的
4
個字節是一個整數,那么你可以使用
BitConverter
類來將這四個字節解析為一個整數,
......
如此,一直將所有字節流解析完畢,生成一個完整的
“
消息對象
”
。至于字節流中的第幾個字節放什么內容,那是你的構建應用時必須定義好的--消息協議。所有的消息協議都實現
IContract
接口。在此基礎之上,應用系統才可以在不了解協議內部細節的情況下,對所有的消息進行統一的處理(這就是
“
多態
”
的應用啊),如此才有可能實現系統運行中動態加載功能插件的能力。
ESFramework
是一個框架,它不關注你具體應用中的具體消息協議,它只關注
IContract
接口,這樣
ESFramework
框架才可以在不同的應用中復用。如果要使
ESFramework
框架幫助我們構建應用時更加容易,
ESFramework
就需要把我們應用中更多共性提取出來,那么它必須
“
標準化
”
更多的東西,
IContract
只是其中的一個。接下來的文章中你會看到
NetMessage
的引入,系統之間通過網絡交互的消息都可以表示成
NetMessage
,并且
NetMessage
游走于系統內部的各處理器、鉤子
Hook
之間,正是由于這種前后一致性,使得
NetMessage
成為
ESFramework
的核心要素之一,關于
NetMessage
的具體介紹請留意下篇文章:
ESFramework
介紹之(
2
)――網絡通信消息
NetMessage
轉到:
ESFramework 可復用的通信框架(序)
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
