資料拼接三要素

2021-10-04 19:14:07 字數 2992 閱讀 8682

~

超時是每個程式設計師學習串列埠程式設計最初結識的引數,雖然超時的效果不是很理想,但超時是最簡單的方法。

超時的判定有兩種實現,一種是接收到最後的碎片開始計時,直到計時完畢就觸發超時事件;另一種是用時鐘脈衝來區分時間片,如果某乙個時間片沒有收到碎片,就觸發超時事件。

顯然,分時間片的方法需要有乙個後台時鐘執行緒,多出來乙個執行緒就多出來乙個麻煩。不建議使用劃時間片的方法。

考慮到開發難度,微控制器程式可能只有超時限制,這時只要不間斷地對微控制器進行傳送,微控制器的記憶體就會重複溢位,然後一直觸發看門狗,重複復位,導致程式無法正常執行。這就是對微控制器的串列埠攻擊。可見如果執行環境的安全性得不到保證,不論是微控制器還是上位機,都不可以僅僅依賴超時。

~正常的報文總是乙個有限的數字。可想而知,假設存在一種無限長度的報文,那麼目標機器永遠無法完成報文接收,也就永遠無法執行操作,這個報文也就沒有意義了。沒有意義的報文屬於網路攻擊,不是正常的通訊。我的建議是作為接收端的程式,不需要幫助完成網路攻擊。每一種通訊規約都包含有乙個長度限制,比如modbus約定報文長度限制256位元組,mqtt約定長度限制0x1fffffff位元組。不得不說,有些規約的長度約定實在太長了,幾乎超過了作業系統為應用程式分配的記憶體空間。這種情況下預期長度基本上不起作用。但是通常的報文實際長度總有乙個比較小的上限。我見過的最長的modbus報文也就30多個位元組,最長的mqtt大約1kb,645規約30個位元組也差不多了。

有了長度限制,就可以很好地防止通訊干擾的情況下無限接收的故障。對於固定長度的報文,預期長度的限制是乙個很好的避免最終超時以節約時間的方法。

~預校驗是指在接收過程中,對報文質量的判定。它包括預確認和預丟包兩種情況。

對於有報頭和報尾的規約,可以在接收過程中檢查報文格式是完整性。當出現沒有報頭的情況下,可以不等待後面的資料,直接返回已經收到的錯誤資料片(薦)或清除快取重新下一輪接收。如果檢測到格式已經完整,則可以直接返回合格的報文,不再進入超時等待的過程。

對於格式不封閉,但有校驗碼的規約,可以用校驗碼先行判定報文是否已經完整。理論上講,格式不封閉的規約有可能碰巧讓不完整的報文碎片通過驗證,但概率極小,而且還可以通過提前解碼進一步確認報文碎片是否合格。

當判定報文碎片合格或完整以後,就可以直接返回,節省了無意義的超時時間。無明確判定時,進入超時等待,試圖讓報文完整。當判定報文碎片不合格的時候,有兩種選擇,一是返回不合格的碎片,二是清除快取,重新接收。我推薦的是返回不合格的碎片,讓邏輯層去丟包。多數情況下,傳送端無法確認自己的資料被丟棄。等待的結果一般就是白忙活一場,浪費時間而已。而把不合格的碎片交給邏輯層,邏輯層可以更快地下令發起新的訪問,反而節省時間。

/**

* 資料拼接地接收

* * @deprecated 如果輸入io是長期阻塞型,則會卡死。

* @param io

* @param timeout

* @param linelimit

* @param breakcondition

* @return

*/public

static

communicationmessage

> message_type receivewithdatastitching

( communicationio

io,int linelimit, predicate<

byte

> breakcondition)

/** * 資料拼接地接收

* * @param io

* @param timeout

* @param linelimit

* @param breakcondition

* @return

*/public

static

communicationmessage

> message_type receivewithdatastitching

( bufferedreceivable

io,long timeout,

int linelimit,

predicate<

byte

> breakcondition)

/** * 資料拼接地接收

* * @param supplier

* @param timeout

* @param linelimit

* @param breakcondition

* @return

*/public

static

communicationmessage

> message_type receivewithdatastitching

( supplier

supplier,

int linelimit,

predicate<

byte

> breakcondition)

lastrecvmsg.

accept

(abuffer.

tobytearray()

);return staticdatautils.

castobject

(lastrecvmsg);}

if(recvmsg.

get(

)== null)

lastrecvmsg = recvmsg;

// 避免返回型別為communicationmessage而需要的返回型別是其子類造成型別轉換錯誤

abuffer.

write

(recvmsg.

get())

;byte

currentbytes = abuffer.

tobytearray()

;if(currentbytes.length >= linelimit)

if(breakcondition != null && breakcondition.

test

(currentbytes))}

}catch

(ioexception e)

}

成功三要素

乙個人要想成功,以下三要素是必不可缺的。1 努力。乙個人成功的人士,必須有為了自己的事業拼搏的那種執著。乙個沒有恆心,不能吃一點苦的人,成功的可能性是很渺茫的。完成一件事情,興趣很重要,但不能只憑興趣。因為一件事情,不會是從開始到結束都是能讓你鬥志昂揚的。他會有一段平淡期,甚至低谷期,這時候,就需要...

事件三要素

dom 文件物件模型 bom 瀏覽器物件模式 js以事件驅動為核心的一們語言 事件三要素 1 事件源 a 執行者 b 誰引發的事件,事件的標籤,動作 2 事件 a 執行的事情 b 已經定義好的 點選,滑鼠移上 3 事件驅動程式 處理元素 a 執行結果 b 對樣式和html標籤的 dom操作 執行事件...

成功三要素

乙個人要想成功,以下三要素是必不可缺的。1 努力。乙個人成功的人士,必須有為了自己的事業拼搏的那種執著。乙個沒有恆心,不能吃一點苦的人,成功的可能性是很渺茫的。完成一件事情,興趣很重要,但不能只憑興趣。因為一件事情,不會是從開始到結束都是能讓你鬥志昂揚的。他會有一段平淡期,甚至低谷期,這時候,就需要...