日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

ESFramework介紹之(4)――消息攔截器INetMess

系統(tǒng) 1900 0
網(wǎng)絡(luò)上傳輸?shù)南⒔?jīng)常是經(jīng)過(guò)加密和壓縮,有的特定類型的消息可能還需要進(jìn)行其它變形, ESFramework 通過(guò) INetMessageHook 對(duì)這些功能提供支持。需要說(shuō)明的是, ESFramework 對(duì)消息進(jìn)行截獲( Hook )處理有兩種方式,一是僅僅 Hook 處理消息主體( Body ),而不對(duì)消息頭作任何變換;另一種方式是對(duì)整個(gè)消息(包括消息頭和主體)都進(jìn)行 Hook 處理。通常,第一種方式已經(jīng)能夠滿足我們的大多數(shù)應(yīng)用,并且效率也更高,如果應(yīng)用有更特殊的要求,可以采用第二種方式。本文先介紹第一種方式,后面的文章中會(huì)對(duì)第二種給予講解。

INetMessageHook 定義如下:
ESFramework介紹之(4)――消息攔截器INetMessageHook

1 public interface INetMessageHook
2 {
3 // 轉(zhuǎn)換消息
4 NetMessageCaptureRecievedMsg(NetMessagemsg); // 在交給處理器之前
5 NetMessageCaptureBeforeSendMsg(NetMessagemsg); // 在發(fā)送出去之前
6
7 bool Enabled{ get ; set ;} // 是否啟用本Hook
8 }

通過(guò) INetMessageHook 接口可以看到,當(dāng)消息進(jìn)入系統(tǒng)時(shí)回被 CaptureRecievedMsg 方法截獲(比如,進(jìn)行解密處理),當(dāng)把消息發(fā)送到網(wǎng)絡(luò)之前,將被 CaptureBeforeSendMsg 方法截獲(比如,進(jìn)行加密處理)。

如果有多個(gè) INetMessageHook ,則可以形成一個(gè) HookList ,消息經(jīng)過(guò) HookList 時(shí),分別按順序被每個(gè) INetMessageHook 處理, ESFramework 中的 HookList 的參考實(shí)現(xiàn)是 EsbNetMessageHook ,并且它也實(shí)現(xiàn)了 INetMessageHook 接口,這樣就可以把一個(gè) Hook 鏈當(dāng)作一個(gè) Hook 了。
ESFramework介紹之(4)――消息攔截器INetMessageHook
其源碼如下:

EsbNetMessageHook
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> 1 public class EsbNetMessageHook:INetMessageHook
2 {
3 #region property
4 private IListhookList = new ArrayList();
5 public IListHookList
6 {
7 set
8 {
9 this .hookList = value;
10 }
11 }
12
13 #region Enabled
14 private bool enabled = true ;
15 public bool Enabled
16 {
17 get
18 {
19 return this .enabled;
20 }
21 set
22 {
23 this .enabled = value;
24 }
25 }
26 #endregion
27
28 #endregion
29
30 #region INetMessageHook成員
31 public NetMessageCaptureRecievedMsg(NetMessagemsg)
32 {
33 if ( ! this .enabled)
34 {
35 return msg;
36 }
37
38 if (msg == null )
39 {
40 return null ;
41 }
42
43 NetMessageresult = msg;
44 for ( int i = 0 ;i < this .hookList.Count;i ++ )
45 {
46 INetMessageHookhook = (INetMessageHook) this .hookList[i];
47 result = hook.CaptureRecievedMsg(result);
48 }
49
50 return result;
51 }
52
53 public NetMessageCaptureBeforeSendMsg(NetMessagemsg)
54 {
55 if ( ! this .enabled)
56 {
57 return msg;
58 }
59
60 if (msg == null )
61 {
62 return null ;
63 }
64
65 NetMessageresult = msg;
66 for ( int i = this .hookList.Count - 1 ;i >= 0 ;i -- )
67 {
68 INetMessageHookhook = (INetMessageHook) this .hookList[i];
69 result = hook.CaptureBeforeSendMsg(result);
70 }
71
72 return result;
73 }
74
75 #endregion
76 }

需要特別注意的是, HookList 的實(shí)現(xiàn)中,逐個(gè)調(diào)用 Hook CaptureRecievedMsg 方法的順序必須與逐個(gè)調(diào)用 CaptureBeforeSendMsg 方法的順序相反,這就是為什么 EsbNetMessageHook 實(shí)現(xiàn) CaptureBeforeSendMsg 方法時(shí),出現(xiàn)下列代碼的原因:

for ( int i = this .hookList.Count - 1 ;i >= 0 ;i -- )

為了說(shuō)明為什么需要顛倒 Hook 鏈的情況,可以舉個(gè)例子,假設(shè)有一個(gè)“原始消息”從系統(tǒng) 1 發(fā)送到系統(tǒng) 2 ,其間經(jīng)過(guò)了兩個(gè) Hook ,一個(gè)加密 Hook ,一個(gè)是壓縮 Hook ,則可表示如下:
系統(tǒng) 1 =》原始消息=》加密=》壓縮=》發(fā)送
系統(tǒng) 2 =》接收消息=》解壓縮=》解密=》原始消息

還要提醒的是,在具體的 Hook 實(shí)現(xiàn)中,截獲處理經(jīng)常改變 Body 的大小,如果 Body 的大小真的發(fā)生了變化,一定要更新消息頭( IMessageHeader )中的 MessageBodyLength 字段。

通常,采用Hook時(shí),服務(wù)端與客戶端是對(duì)稱的,所以你可以把所有的Hook實(shí)現(xiàn)放在一個(gè)Dll中,這樣服務(wù)端和客戶端可以共同使用這個(gè)Hook Dll了。

由于對(duì)網(wǎng)絡(luò)消息進(jìn)行壓縮是常見(jiàn)的需求,所以我把
BaseZipHook 納入到了 ESFramework 中,并且,這也是 IMessageHeader 存在 ZipMe 屬性的原因。 ZipMe 屬性用于通知 BaseZipHook 是否對(duì)接收到的本條消息進(jìn)行解壓縮,是否在發(fā)送本消息之前進(jìn)行壓縮。
ESFramework介紹之(4)――消息攔截器INetMessageHook
BaseZipHook
實(shí)現(xiàn)如下:

BaseZipHook
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--> 1 public abstract class BaseZipHook:INetMessageHook
2 {
3 public BaseZipHook()
4 {
5 }
6
7 protected abstract byte []Zip( byte []data, int offset, int size);
8 protected abstract byte []Unzip( byte []data, int offset, int size);
9 protected abstract bool IsP2PMessage(NetMessagemsg);
10
11 #region INetMessageHook成員
12
13 #region CaptureRecievedMsg
14 public NetMessageCaptureRecievedMsg(NetMessagemsg)
15 {
16 if ( ! this .enabled)
17 {
18 return msg;
19 }
20
21 if ( ! msg.Header.ZipMe)
22 {
23 return msg;
24 }
25
26 if ( this .IsP2PMessage(msg))
27 {
28 if ( ! this .zipP2pMessage)
29 {
30 return msg;
31 }
32 }
33
34 if (msg.Body == null )
35 {
36 return msg;
37 }
38
39 msg.Body = this .Unzip(msg.Body, 0 ,msg.Header.MessageBodyLength);
40 msg.Header.MessageBodyLength = msg.Body.Length;
41
42 return msg;
43 }
44 #endregion
45
46 #region CaptureBeforeSendMsg
47 public NetMessageCaptureBeforeSendMsg(NetMessagemsg)
48 {
49 if ( ! this .enabled)
50 {
51 return msg;
52 }
53
54 if ( ! msg.Header.ZipMe)
55 {
56 return msg;
57 }
58
59 if ( this .IsP2PMessage(msg))
60 {
61 if ( ! this .zipP2pMessage)
62 {
63 return msg;
64 }
65 }
66
67 if (msg.Body == null )
68 {
69 return msg;
70 }
71
72 msg.Body = this .Zip(msg.Body, 0 ,msg.Header.MessageBodyLength);
73 msg.Header.MessageBodyLength = msg.Body.Length;
74
75 return msg;
76 }
77 #endregion
78
79 #region Enabled
80 private bool enabled = true ;
81 public bool Enabled
82 {
83 get
84 {
85 return this .enabled;
86 }
87 set
88 {
89 this .enabled = value;
90 }
91 }
92 #endregion
93
94 #region ZipP2pMessage通常服務(wù)端設(shè)置為false,而客戶端設(shè)置為true
95 private bool zipP2pMessage = true ;
96 public bool ZipP2pMessage
97 {
98 get
99 {
100 return this .zipP2pMessage;
101 }
102 set
103 {
104 this .zipP2pMessage = value;
105 }
106 }
107 #endregion
108
109 #endregion
110 }

BaseZipHook 是一個(gè)抽象類,具體實(shí)現(xiàn)的壓縮算法由派生類通過(guò)覆寫 Zip Unzip 方法提供。如果要實(shí)現(xiàn)一個(gè)具體的 ZipHook ,你可以從 BaseZipHook 繼承,并采用 ZipHelper 提供的壓縮 / 解壓縮功能。

到現(xiàn)在為止,我們已經(jīng)討論了關(guān)于消息的比較多的內(nèi)容了,但還有一個(gè)非常重要的組件沒(méi)有講到,那就是消息分派器 ITcpStreamDispatcher ,消息分派器直接與 Tcp 組件或 Udp 組件聯(lián)系,并且所有消息的進(jìn)出都要經(jīng)過(guò) ITcpStreamDispatcher ,所以分派器是一個(gè)對(duì)消息進(jìn)行 Hook 的理想位置,并且消息分派器會(huì)把具體的消息分派到對(duì)應(yīng)的消息處理器上。欲知道 ITcpStreamDispatcher 的原理與實(shí)現(xiàn),請(qǐng)繼續(xù)關(guān)注下文:

ESFramework 介紹之( 5 ―― 消息分派器 ITcpStreamDispatcher


上一篇: ESFramework介紹之(3)――消息處理器和處理器工廠

轉(zhuǎn)到: ESFramework 可復(fù)用的通信框架(序)



ESFramework介紹之(4)――消息攔截器INetMessageHook


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 德州市| 修武县| 岳阳县| 黎城县| 娱乐| 大连市| 大庆市| 湖州市| 铁岭县| 綦江县| 肇东市| 雅江县| 金坛市| 肥乡县| 广东省| 新沂市| 普洱| 安化县| 定安县| 阜新市| 永寿县| 兴宁市| 武隆县| 武胜县| 炉霍县| 合阳县| 柳江县| 新沂市| 乐东| 芒康县| 本溪| 定边县| 五常市| 聊城市| 金山区| 喜德县| 永城市| 北安市| 水富县| 平和县| 甘肃省|