1. 程式人生 > >C# 串列埠操作系列(5)--通訊庫雛形

C# 串列埠操作系列(5)--通訊庫雛形

串列埠是很簡單的,編寫基於串列埠的程式也很容易。新手們除了要面對一堆的生僻概念,以及跨執行緒訪問的細節,還有一個需要跨越的難題,就是協議解析,上一篇已經說明了:

一個二進位制格式的協議一般包含: 協議頭 + 資料段長度 + 資料  + 校驗

一個Ascii格式的文字協議,一般包含: 資料頭 + 正文 + 資料結束標識

類似的命令可能很多,類似的程式碼也會重複寫很多次。對於我,並不覺得這個有任何難度,但是,很多時候,需要寫點類似東西的時候呢,我往往不想寫,不是別的,要搭建一個這樣的框架,這絕對是個體力活,而且還需要耐心細心

從我上一次帶專案,我就開始考慮編寫通用的一個通訊庫,支援很多功能,不過和公司內容結合緊密,不適合開源,更不適合推廣。我重新組織、抽象了各個概念。希望能讓新人朋友減少學習難度,更快的投入到其他方面。

請注意,此文章我也不知道如何歸納,不算科普,不能算類庫的介紹,我是在介紹如何設計一個這樣的通訊庫

通訊庫,並非串列埠庫,所以,我希望有一個基類,可以描述各種通訊方法的基類或介面,微軟已經這麼做了,他把這個叫做Stream。我認為不好的理由是,提供了Length屬性、peek方法、seek方法卻無法使用,很多方法和屬性是不支援的,如果使用這個類操作硬體,就像一顆地雷,不小心就會寫一個不支援的操作,而且會在執行時報錯。所以,我希望能針對流裝置的硬體,重新設計,我抽象出了一個介面:ICommunication。提供基本的開啟、關閉、讀寫、字符集和有效資料長度等流裝置的特性和操作。

為了能有一個通用的配置類

,我定義了一個介面:ICommunicationSetting

當你實現一個裝置的時候,你需要實現ICommunication,還需要編寫一個設定的類,去實現ICommunicationSetting介面。別覺得麻煩,這是為了能抽象的好,編寫一個一勞永逸不用經常重寫的通用程式碼。有了2個介面,我甚至可以開始編寫依賴此介面的功能或軟體了。當然,我還有需要寫有關協議的分析。

既然協議是分2種,那自然要編寫BinaryXXXTextXXX,沒錯,有這樣2個類。

考慮的更詳細一點,任何資料,都不是無限期有效的,比如你獲取下位機發來的電壓,過了幾秒了,應該就無效了,所以要考慮定時失效,於是我實現了有效性檢查。資料要在位元組陣列中查詢,分析,通知。所以這些公共的部分,我抽出來了,我寫了一個介面,叫做:IAnalyzer

,並編寫了預設的實現,於是有了AnalyzeResult類,同時,區分2種協議方式,建立了子類:BinaryAnalyzeResultTextAnalyzeResult

那麼,誰來使用ICommunication,IAnalyzer呢?放心,聯絡有點緊密,我不會撒手扔給外面的,這樣做反而更復雜了,不是麼。所以我寫了一個帶有分析功能的類:WyzComm

使用通訊庫的

這個類實現了資料的採集、快取、分析器的呼叫,以及事件呼叫的通知。資料死鎖的控制,所有你認為的麻煩事情,都在這裡做了。那麼,我編寫這個類的時候,我肯定不知道未來有多少種協議是不是?那怎麼辦呢?我無法寫死分析器,所以,我編寫了介面:IAnalyzerCollection,因為文章從串列埠說起,我首先提供了串列埠的實現:

SerialPort(此類和微軟的那個名字一樣而已,但不是同一個),實現了ICommunication介面,我定義了一個SerialPortSetting類,實現了ICommunicationSetting。

至此。通訊庫的框架就完成了。而這也就是使用通訊庫所需要關注的所有內容。下面,為了能進行實際的演示,我編寫了簡單的實現。來演示一種功能,假設我有個程式,需要同時分析二進位制資料格式和ASCII的文字資料格式,資料各不相同,使用了通訊庫之後,我不需要重寫資料的快取、關閉的死鎖處理、資料對介面的通知。我只需要編寫2個協議類,和1個協議集合類。我的資料分析工作就完成了。

首先是一個文字協議,協議頭是WYZ,協議尾是回車換行,中間是一個整形數字。我只需要設定好頭、尾,編寫資料分析。

然後我定義了一個二進位制協議,分析一條資料包含2個子項。

我首先定義這個資料的具體型別

然後我編寫協議分析類

完成了。一個基於串列埠的,同時分析2種資料的,資料具有有效性判斷,支援獨立資料通知介面,整體原始資料快取顯示的功能。完成了。

為了演示功能,我寫了新的校驗方式,當然,你不用管,預設已經支援了異或校驗,後續還會把常用校驗都新增進去,crc16,crc32,奇偶校驗等。

模擬傳送資料為:

文字格式傳送:WYZ123<CR><LF>

二進位制格式傳送:AA BB CC 08 0A 00 00 00 FA 3E F7 42 05