早就註冊了部落格園,卻只在最近才開始關注,呵呵,錯過了好多學習的機會。
第一次在園子裡寫部落格,如寫的有不恰當、不合理、錯誤之處,敬請拍磚~。
前一段時間做了一個Socket底層通訊的項目,採用TCP協議,上位機作為用戶端,下位機作為伺服器端。在做的過程中遇到了好多問題,諸如非同步發送、接收、多線程、逾時重傳等等。在此把該項目拿出來,將項目的各個過程,涉及到得知識,通訊中常用的資料處理方式(封裝成了DLL),竭盡自己所能,寫出來與大家一同分享,如有不好之處,敬請指正。
一、TCP協議
相信做通訊的對TCP、UDP都不陌生。二者主要的區別有TCP是連線導向的、UDP面向不需連線的;TCP是可靠的資料轉送,有三向交握來保證資料的可靠性,UDP是不可靠的傳輸;TCP傳輸速度相對於UDP要慢。
具體涉及到TCP封包等等,我是菜鳥級的,懂的不多,留給大蝦、大牛來講吧,當然網上也有好多這方面的知識啦~。
選擇TCP協議的原因,是我們的儀器檢測的都是高危險的東西,所以要保證傳輸命令的正確性、可靠性。
二、協議格式
請求資料命令格式(上位機發送)
標識號(1位元組)+資料包長度(1位元組)+命令字(1位元組)+命令序號(1位元組)+具體命令(可以為0位元組,具體內容,由上下位機來定)+校正碼(1位元組)
說明:
- 標識(1位元組),只是對硬體的一個標識,一般用0xFN標識,其中N介於1到F之間,當然標識可以進行擴充,如果說儀器比較多,那標識從0xEN開始也無妨。
- 命令包長度(1位元組),是從標識到最後驗證碼的所有資料的位元組長度。
- 命令字(1位元組),指示當前通訊的命令,例如,0XC1標識設定參數命令。
- 命令序號(1位元組),是該資料包的一個時序上面的標識。十進位範圍是1-255,當超過255時,對256求餘,如果餘數為0,則設定命令序號為1,從1開始遞增。
- 具體命令就不說了,也就是資料包的核心東西吧,下位機需要的狀態等等資訊都包括在這裡面。到後面,我會舉例子。
- 校正碼(1位元組),這裡校正碼是這樣制定的:整條命令中,除校正碼本身外的所有位元組相異或。原本是打算使用整條命令中,除校正碼本省外所有位元組相加取結果的最後1個位元組,不管溢出與否。但是相加沒有異或快,而且考慮到相加容易溢出,就摒棄了這種擷取校正碼的一種方式。
發送資料命令格式(下位機發送)
標識號(1位元組)+資料包長度(1位元組)+命令字(1位元組)+命令序號(1位元組)+儀器狀態(1位元組)+具體命令(可以為0位元組,具體內容,由上下位機來定)+校正碼(1位元組)
說明:儀器狀態(1位元組)指示當前儀器是否正常工作,有沒有故障資訊等等。命令字和命令序號是從接收到得上位機命令中直接拷貝過來的,不用改變,其它的參照 請求資料命令 的說明。
上面是純粹的協議,是在網路傳輸封裝之前的協議,在資料包進行傳輸的過程中,傳輸層以及網路層都會對它添加資訊,這是網路傳輸的事。
三、上位機逾時與重發
上位機發送命令給下位機,下位機收到命令後返回相應資訊,1秒鐘上位機收不到響應資訊或者收到得不是期望的響應資訊(格式錯誤或者命令字錯誤或者命令序號錯誤或者資料包長度不完整等等),則認為本息通訊過程失敗。
通訊失敗後,上位機重發命令(命令字和命令序號不變),如果連續三次通訊過程失敗,則認為通訊出錯,終止通訊並彈出提示性資訊。
四、下位機逾時與重發
在測量過程中,如果下位機3秒鐘之內收不到上位機發送的任何命令,則通訊出錯,關閉儀器電源。
五、心跳包檢測
鑒於上位機有時需要等待使用者的某些操作才能發命令給下位機,類似這種情況,在協議中加入心跳包。其作用是為了防止正常通訊過程中,由於上位機的一些命令傳輸延遲(比如等待接收使用者輸入),下位機誤以為逾時,以至於中斷了通訊過程。
心跳包採用定時1秒鐘發送一次。只在正常通訊時,上位機需要做某些操作或等待使用者的操作等,以至於通訊處於空閑狀態,此時,上位機發送給下位機命令。