背景:驗證設備遠程升級的協議方案可行性
其實是很簡單的一個處理過程,首先設備能夠聯網,與遠程伺服器建立連接,通過SOCKET建立雙向連接,為了保證通信可靠,採用TCP的方式。
下面具體描述逐步實現的過程。
首先、平臺方案確定
設備端:設備主MCU為STM32F103,外接一個4G模塊來中轉數據,4G模塊的通信接口為串口。
伺服器端:簡易起見,使用國內雲大廠--阿里雲,然後是伺服器開發語言的選擇。本來考慮採用基於C++的QT進行開發,因為C語言使用多年,已經習慣了基於C的各種開發工具。但是發現還有幾天時間,於是想到人工智慧很火的Python語言,要不試試寫下Python腳本。
其次、環境安裝
因為網絡帶寬要求不高,阿里雲伺服器申請最便宜的、預訂一星期時間(省點錢),基於Window作業系統的(用習慣了),然後進行組策略配置,開放10000埠給TCP Server使用。
下載Python3.x版本,現在的軟體安裝做得很人性化了,按下一步操作安裝,環境變量也給配置好了。
然後、開始學習Python
整本書,花了2天時間認真學習了一下Python,初看其跟C語言很相似,細看好像又有些不同。
列幾個比較不習慣的差異。
1、變量類型就一個整數類型,沒有Char、Short類型區分,通過賦值給變量來確定類型,根據數值的位數自動決定數據類型。
intValue = 255 #char型
intValue += 2 #自動提升為short型
2、沒有數組,取而代之的是列表,列表的功能比數組更加強大。
intList = [1,10,20,100] #列表定義
intList[0] = 2 #類似C語言數組的操作
intList.append(200) #列表可擴展
3、新增了字典類型((鍵:值)形式),看完後發現功能非常強大。
intDict = {0:10,1:20,2:30} #字典的定義
intDict[0] = 100 # 類似C語言數組的操作
重要的是:鍵(key)是不可變的,可以為字符串、數字類型;值(value)可以任意數字類型,這就是字典強大的地方。
4、指針哪裡去了?把這討厭的指針給隱藏了。
接著、開始構思設計
對於設備端比較簡單,不做介紹。
對於伺服器端,採用多線程模塊化(模塊化是我的最愛)設計,如下設計結構。
主線程目前只用於創建子線程,沒其他用途;
Tcp Socket線程主要用於開啟Tcp伺服器監聽,專注於數據接收與發送;
Data Pro線程專注於根據實際的業務邏輯進行數據處理。
然後、編碼調試
因為代碼量小,Tcp Socket線程模塊與Data Pro線程模塊均放在一個文件內,如下代碼(親測可用);
con_list列表保存連接的socket句柄;
out_list列表保存有數據要發送的socket句柄;
message_rddict字典保存接收的數據;
message_wtdict字典保存發送的數據。
數據處理模塊:接收設備的數據,按業務邏輯處理(本方案為發送升級數據包)。
Tcp Socket線程不斷地監聽設備的Tcp Client連接,然後將接收的數據傳送給data proc線程處理;同時,將data pro線程的需要發送的數據,通過socket發送出去。
主線程就是建立兩個子線程。
接著、調試花絮
1、python2跟python3版本兼容性問題
比如在python2的線程庫為thread,而python3並不支持,為了兼容python2,其提供了_thread庫。
2、python數據類型問題
正常數據會保存於列表或字典中,然後由socket進行發送,但是socket的函數接口
sendall(bytes(xxxx)),接收bytes型的字節流,因此發送前,需要將list轉bytes,如bytes(xxxx)。
相反,bytes轉list為list(xxxx)。
最後、總結
經過幾天調試,發現python能夠被大家所接受是有其原因的:
1、語法簡單,沒有了C語言的指針與內存分配釋放問題,雖然剛開始用時有些彆扭;
2、代碼簡單,提供了豐富的庫支持,簡單地調用就實現了功能,這也是能快速完成的原因。