從這篇起要開始慢慢以較為複雜的方式來寫程式,開始要進入自訂類別的初步練習,我會儘量地將步驟拆解的詳細一些,這也意味著每一篇產出的間隔時間也可能會拉長。
從這篇起要開始慢慢以較為複雜的方式來寫程式,開始要進入自訂類別的初步練習,我會儘量地將步驟拆解的詳細一些,這也意味著每一篇產出的間隔時間也可能會拉長。
拆解通訊協定
首先我們得將通訊協定切分成兩個部份,一個是要產生發送的資料;另一個則是解譯接收回來的資料。
為了簡便大家瞭解先來製作一個圖解說明 (上圖),先來拆解比較固定的資料:
(1) 開頭碼固定為 249
(2) 接收者因方向不同可能是0或1
(3) 命令在發送時是 81,82,83 ;而在接收時會多出 99
然後我們再進一步思考這兩個流程的部份相關內容:
發送 | 接收 |
從上圖的比較來看,在長度碼的部份兩方是不同的方式,在發送一方是由資料內容計算發送陣列的長度碼與總長;而接收的一方則是由讀取的陣列總長度和長度碼比較。不過 XOR 的部份我們就要特別注意了,不論發送或接收都要做一樣的計算,發送要計算這無庸置疑;但為什麼接收也要計算,它不是在讀取陣列的最後一個元素就是XOR值嗎?原因是因為我們必須確認這個XOR是對的,所以必須重新計算一次再做比對。
由上面的討論發現不論發送或接收的部份都有一些相同點,所以在這個步驟先來建立一個未來要給發送協定類別與接收協定類別所繼承的抽象類別,這個抽象類別將會具有以下的成員:
(1) 開頭碼的唯讀屬性
(2) 命令碼的列舉
(3) 接收者的列舉
(4) 計算 XOR 值的方法
程式碼內容如下:
Public MustInherit Class Protocol
Public Enum CommandCode As Byte
ReadBlock = 81
WriteBlock = 82
LightControl = 83
DataError = 99
End Enum
Public Enum Direction As Byte
DeviceToPC = 0
PCToDevice = 1
End Enum
Public ReadOnly Property Head As Byte
Get
Return 249
End Get
End Property
Protected Function GetXorValue(ByVal fullBytes As Byte()) As Byte
Dim result As Byte = 255
For i As Int32 = 0 To fullBytes.Length - 2
result = result Xor fullBytes(i)
Next
Return result
End Function
End Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RequestResponse001CS
{
abstract class Protocol
{
public enum CommandCode : byte
{
ReadBlock = 81,
WriteBlock = 82,
LightControl = 83,
DataError = 99
}
public enum Direction : byte
{
DeviceToPC = 0,
PCToDevice = 1
}
public Byte Head
{ get { return 249; } }
protected Byte GetXorValue(Byte[] fullBytes)
{
Byte result = (Byte)255;
for (Int32 i = 0; i <= fullBytes.Length - 2; i++)
{
result = (Byte)(result ^ fullBytes[i]);
}
return result;
}
}
}
【備註】由此開始會漸漸地使用到一些物件導向程式設計的基本概念,如果你感覺看得有點吃力,那就不應該急著繼續看下去,這時候的你應該回頭把一些基本的概念弄通,可以參考之前兩篇
[對初心者有助益的 MSDN 文件庫索引整理 (一)]、[對初心者有助益的 MSDN 文件庫索引整理 (二) ] 閱讀其中的相關資料,而且把這概念弄懂;當然最佳的方式是能去找幾本把物件導向基礎寫得很清楚的書來讀一讀。