許建淼,馬天才 Xu Jianmiao,Ma Tiancai
?
燃料電池汽車遠程監(jiān)控中服務(wù)器的設(shè)計和實現(xiàn)
許建淼,馬天才 Xu Jianmiao,Ma Tiancai
(同濟大學(xué) 汽車學(xué)院,上海 201804)
為滿足燃料電池汽車遠程監(jiān)控中的車載終端和服務(wù)器通信的基本要求,以SocketServer庫為基礎(chǔ),基于Python語言開發(fā)實現(xiàn)了服務(wù)器和車載終端的多線程非堵塞通信;并在此基礎(chǔ)上加入密碼驗證和IP黑名單,滿足了服務(wù)器的基本安全需要;加入超時連接處理功能進行了性能優(yōu)化;利用Threading庫設(shè)計了車載終端管理臺,實現(xiàn)了服務(wù)器對車載終端的主動控制。
非堵塞多線程通信;安全通信;車載終端管理臺;汽車遠程車載監(jiān)控
我國燃料電池汽車正處于商業(yè)化示范運行考核與應(yīng)用階段[1]。為實現(xiàn)“十三五”規(guī)劃中提出的“燃料電池汽車要產(chǎn)業(yè)化,到2020年要實現(xiàn)燃料電池車批量生產(chǎn)和規(guī)?;痉稇?yīng)用”的目標,國家近幾年大力扶持相關(guān)企業(yè)。為了規(guī)范市場,國家新能源補貼政策里明確規(guī)定燃料電池汽車的在線遠程監(jiān)控是強制必要的。因此,如何實現(xiàn)燃料電池汽車的遠程監(jiān)控是實現(xiàn)燃料電池汽車市場化的主要問題之一。
物聯(lián)網(wǎng)可將虛擬世界與物理世界結(jié)合,通過數(shù)字信息可以控制物理世界關(guān)鍵設(shè)備甚至基礎(chǔ)設(shè)備[2]。安全問題在新興物聯(lián)網(wǎng)中并未得到廣泛關(guān)注,但特別重要,這在燃料電池汽車的遠程監(jiān)控中更為突出。所以,在此不拘于實現(xiàn)通信功能,也考慮加入安全功能完善監(jiān)控體系。
Python是一門高級編程語言,SocketServer庫是Python中基于Socket庫的擴展庫。Socket是TCP/IP協(xié)議的基本封裝接口。汽車車載終端考慮到硬件成本和自身的空間大小,系統(tǒng)一般都比較精簡,只支持一些底層網(wǎng)絡(luò)服務(wù)。因此,Python中SocketServer庫特別適合車載終端和服務(wù)器通信的程序開發(fā),所以以此為基礎(chǔ)開發(fā)Socket服務(wù)器。
總體架構(gòu)分為本地端和服務(wù)器端。本地端是車載終端;服務(wù)器端為非堵塞多線程通信和安全通信的Socket服務(wù)器和車載終端管理器。非堵塞多線程通信和安全通信的Socket服務(wù)器可以滿足多臺車載終端即時向服務(wù)器進行數(shù)據(jù)傳輸,服務(wù)器接收到數(shù)據(jù)后,會對車載終端回發(fā)應(yīng)答,通信過程中有IP黑名單和密碼驗證兩種安全手段,在一定程度上保障服務(wù)器的安全性;在服務(wù)器上管理員可以主動選擇車載終端建立連接,對選定的車載終端發(fā)送指令進行遠程控制,便于管理員應(yīng)對車載終端的一系列意外情況,保證車載終端和服務(wù)器的通信穩(wěn)定和安全。具體如圖1所示。
圖1 總體構(gòu)架圖
Socket服務(wù)器主要有兩種功能:非堵塞多線程通信功能和安全通信功能。分別介紹兩種功能的具體設(shè)計和實現(xiàn)。
2.1.1 非堵塞式通信功能
應(yīng)用進程在調(diào)用接收函數(shù)接收報文時,在阻塞模式下,若沒有到達的數(shù)據(jù),則調(diào)用將一直阻塞直到有數(shù)據(jù)到達或出錯;而在非阻塞模式下,將直接返回而不需等待。因此,非堵塞式通信相較于堵塞式通信,可以充分利用服務(wù)器的資源快速處理各個車載終端的連接,提高通信效率。
Python中Select庫是對底層操作系統(tǒng)的直接訪問的接口,可以監(jiān)控sockets、files和pipes,等待IO完成,當有可讀、可寫或者異常事件產(chǎn)生時,可以做出響應(yīng)。所以,使用Select庫監(jiān)聽sockets,可以較容易地實現(xiàn)非堵塞通信。
with _ServerSelector() as selector:
selector.register(self,selectors.EVENT_ READ)
while not self._shutdown_request:
ready = selector.select(poll_interval)
if ready:
self._handle_request_noblock()
其中,poll_interval為select循環(huán)執(zhí)行時間,程序中poll_interval=0.5,即每0.5 s對sockets進行一次監(jiān)聽,其他時間釋放資源。當有車載終端接觸服務(wù)器,select在下一個0.5 s后執(zhí)行時監(jiān)聽到數(shù)據(jù),立即響應(yīng)執(zhí)行下一步操作即執(zhí)行self._handle_request_noblock函數(shù)。由此實現(xiàn)非堵塞式通信。
2.1.2 多線程通信功能
線程是系統(tǒng)分配處理器時間的基本單元,一個進程中可以有多個線程同時執(zhí)行代碼,實際上,同一時間只有一個線程在運行,處理器通過分時在各個線程間頻繁切換,因為時間間隔很短,所以感覺是多線程同時進行。多線程有利于充分利用服務(wù)器的資源。
考慮到服務(wù)器的服務(wù)對象車載終端有多臺,設(shè)計多線程通信符合項目的實際需求。多線程實現(xiàn)是依靠SocketServer庫中的ThreadingMixIn類(如下代碼),對BaseServer中的process_request進行重寫,在其中引入Threading庫,將每一個process_request都獨立成一個單獨的線程,并在程序后端RequestHandlerClass的handle函數(shù)內(nèi)采用while循環(huán),將通過驗證的合法車載終端的連接線程保留下來,從而實現(xiàn)多線程通信功能。
class ThreadingMixIn
def process_request(self,request,client_ address):
t=threading.Thread(target=self.process_request_thread,args=(request,client_address))
t.daemon=self.daemon_threads
t.start()
2.1.3 整體功能
1)SocketServer庫的機理說明。
實現(xiàn)最基礎(chǔ)通信的核心在于SocketServer中的BaseServer,它需要2個實參server_ip和RequestHandlerClass。server_ip為本服務(wù)器的地址和開放端口;RequestHandlerClass為車載終端接觸服務(wù)器后的主要處理方法集。BaseServer有兩大方法:handler_request和server_forever。在此采用server_forever,其中包含select函數(shù),實現(xiàn)了非堵塞連接。當車載終端與服務(wù)器接觸時,select會立即做出響應(yīng),調(diào)用_handle_request_noblock函數(shù)。在_handle_request_noblock函數(shù)中起主要作用的是verify_request和finish_request方法,前者在安全通信中用于安全驗證,后者調(diào)用RequestHand- lerClass,執(zhí)行開發(fā)者設(shè)計的一系列操作。finish_ request執(zhí)行完成后調(diào)用shutdown_ request退出,至此整個流程完成。具體程序運行流程如圖2所示,從左至右為代碼的層次結(jié)構(gòu),從上到下為代碼的執(zhí)行前后。
因為要求即時通信,同時具有一定的可靠性,不允許數(shù)據(jù)傳輸中丟包,對數(shù)據(jù)的順序也有要求,所以采用SocketServer庫中的TCPServer。TCPServer類是對BaseServer的繼承,定義了Socket的地址簇、套接字類型和協(xié)議,并且提供了get_request方法(在BaseServer中_handle_ request_noblock中必須調(diào)用的方法),對Base Server在TCP中的運用進行了完善,滿足TCP通信要求。
圖2 程序流程圖
2)SocketServer庫的實現(xiàn)過程。
SocketServer庫中提供給用戶BaseReques- tHandler方法,用于方便編寫B(tài)aseServer所需的RequestHandlerClass實參。在此首先創(chuàng)建Threaded TCPRequestHandler類繼承SocketServer.BaseRequest Handler,并對其中setup,handle,finish函數(shù)進行重寫。setup是開始階段服務(wù)器對嘗試連接的車載終端進行地址解析,并設(shè)置套接字的超時值。handle是BaseRequestHandler內(nèi)的核心代碼,主要包括服務(wù)器處理車載終端的連接的一系列行為,對嘗試連接的車載終端進行密碼驗證;未通過密碼驗證則主動斷開客戶端的連接,通過密碼驗證后服務(wù)器保留此線程,并接受車載終端傳來的數(shù)據(jù)并存入數(shù)據(jù)庫;服務(wù)器對超時未響應(yīng)的車載終端采取主動斷開連接;服務(wù)器對車載終端發(fā)出的指令采取相應(yīng)的響應(yīng)(接收到車載終端發(fā)出exit后,服務(wù)器主動斷開與之連接,釋放出此線程資源)。finish是結(jié)束階段服務(wù)器與車載終端斷開連接后的相應(yīng)行為。
接下來采用ThreadedTCPServer類對Socket Server. TCPServer和ThreadingMixIn進行繼承,具體代碼如下。其中重寫了verify_request函數(shù),即根據(jù)IP黑名單過濾掉非法IP,不允許其與服務(wù)器嘗試連接,保障服務(wù)器的安全(具體介紹在2.2安全通信功能的設(shè)計和實現(xiàn))。
最后在主程序中將本服務(wù)器的IP地址、開放端口號和ThreadedTCPRequestHandler代入ThreadedTCPServer完成配置,然后再使用ThreadedTCPServer. server_forever既可(具體參照如下代碼前兩行)。至此基本上完成了非堵塞多線程通信的整體 功能。
class ThreadedTCPServer(SocketServer. Threading MixIn,SocketServer.TCPServer):
def verify_request(self,request,client_ address):
client_ip = client_address[0]
if client_ip in illegal_ip:
print(client_ip+"為非法IP無法連接服務(wù)器")
return False
else:
return True
安全通信功能主要依靠密碼驗證和IP黑名單,兩者相輔相成,共同實現(xiàn)服務(wù)器的通信安全,如圖3所示。
圖3 安全通信實現(xiàn)簡圖
2.2.1 IP黑名單
IP黑名單為第1層前端驗證。具體作用是將密碼驗證中出現(xiàn)5次以上錯誤的IP放置于IP黑名單,禁止此IP在一定時間內(nèi)連接服務(wù)器,有效地防止不法人員對服務(wù)器進行暴力猜解攻擊,在一定程度上保障服務(wù)器的安全。具體實現(xiàn)在verify_request函數(shù)中,對BaseServer類中的verify_request函數(shù)進行重寫(具體參照上段代碼),對illegal_ip中的IP驗證過濾,拒絕和非法車載終端連接。此函數(shù)在_handle_request_noblock中起作用,即車載終端和服務(wù)器一開始接觸時執(zhí)行。
2.2.2 密碼驗證
密碼驗證為第2層后端驗證。在handle函數(shù)中首先判斷接入IP是否在legal_ip列表,如果在,車載終端和服務(wù)器成功建立連接,如果不在,調(diào)用add_illegal_ip函數(shù)進行驗證。在此函數(shù)中進行密碼驗證:車載終端傳入服務(wù)器的第1波數(shù)據(jù)被要求必須上傳規(guī)定格式的賬號密碼,然后此數(shù)據(jù)被引入check_ip函數(shù)中進行驗證,check_ip會對比數(shù)據(jù)庫中用戶原登記的數(shù)據(jù),對傳入的賬號密碼驗證正誤。通過驗證的車載終端IP加入legal_ip列表中,成為合法用戶,服務(wù)器將和它建立并保持連接,而未通過驗證的車載終端,服務(wù)器會主動和它斷開連接,并且該IP會被記錄在error_ip字典中,此字典記錄了錯誤的IP和錯誤次數(shù),當驗證錯誤次數(shù)達到5次時,該IP會被加入到illegal_ip中,即IP黑名單,illegal_ip會在前端的verify_request中被調(diào)用查詢。
車載終端管理臺的設(shè)計思路是把非堵塞多線程通信和安全通信通過Threading庫集成在一個線程中,并將服務(wù)器對車載終端的主動控制代碼作為一個線程獨立開,以此作為主線程(代碼如下)。其本質(zhì)是主動對已經(jīng)建立連接的多個socket的選擇,從而實現(xiàn)與車載終端有區(qū)別的雙向通信。具體操作為在管理臺上主動選擇想要控制的車載終端的端口號,然后輸入想要發(fā)送的指令,最后發(fā)送此指令到選定的車載終端中。至此,已經(jīng)實現(xiàn)了服務(wù)器與車載終端非堵塞多線程通信、安全通信和主動管理車載終端等一系列功能。
server = ThreadedTCPServer((HOST,PORT),Threaded TCPRequestHandler)
server_thread = threading.Thread(target=server. server_forever)
server_thread.daemon = True
server_thread.start()
while True:
time.sleep(2)
want_port=input('請輸入您想要建立連接的端口號:')
if want_port in client_port:
inp=input('想要發(fā)送的指令是:')
message=inp.encode(encoding="utf-8")
client_socket[client_port.index(want_port)].sendall(message)
else:
print(want_port+'端口無車載終端連接')
為了使服務(wù)器資源合理分配,設(shè)置了超時連接處理,避免服務(wù)器為長時間未響應(yīng)的車載終端消耗資源。功能的實現(xiàn)主要基于套接字的內(nèi)置方法settimeout,即先于BaseRequestHandler的setup函數(shù)內(nèi)調(diào)用self.request的settimeout,并代入設(shè)置好的timeout,最后在handle函數(shù)中調(diào)用如下代碼,從而實現(xiàn)這一功能。
try:
data = self.request.recv(1024)
except socket.timeout:
print(' '+self.ip+":"+str(self.port)+"接收超時,即將斷開連接")
break
為了驗證服務(wù)器功能的可行性和穩(wěn)定性,搭建測試環(huán)境并進行實際測試,車載終端采用STM32主控芯片,通過SIM7100C 4G芯片實現(xiàn)數(shù)據(jù)的采集和發(fā)送;服務(wù)器是騰訊云服務(wù)器。通過一定時間的跟蹤測試發(fā)現(xiàn),開發(fā)的服務(wù)器性能穩(wěn)定,并且基本滿足了燃料電池汽車在線遠程監(jiān)控的所需功能。
以下為各個測試的效果。
1)Socket服務(wù)器的驗證。
(1)安全通信測試
車載終端發(fā)送錯誤密碼后服務(wù)器的反應(yīng)為
('58.41.201.173',17360)嘗試連接中
58.41.201.173非法連接次數(shù):1
58.41.201.173:17360已斷開連接!
車載終端發(fā)送錯誤密碼5次后服務(wù)器的反 應(yīng)為
('58.41.201.173',17365)嘗試連接中
58.41.201.173非法連接次數(shù):5
58.41.201.173:17365已斷開連接!
58.41.201.173為非法IP無法連接服務(wù)器
車載終端發(fā)送正確密碼后服務(wù)器的反應(yīng)為
('58.41.201.173',17379)嘗試連接中
legal_IP['58.41.201.173']
('58.41.201.173',17379)已經(jīng)成功連接
(2)非堵塞多線程通信功能的驗證
單臺車載終端向服務(wù)器發(fā)送消息時服務(wù)器的反應(yīng)為
('58.41.201.173',17379)已經(jīng)成功連接
從17379接收到的信息是:tongji
從17379接收到的信息是:automobile
多臺車載終端向服務(wù)器發(fā)送消息時服務(wù)器的反應(yīng)為
('180.160.22.100',1143)嘗試連接中
legal_IP['180.160.22.100']
('180.160.22.100',1143)已經(jīng)成功連接
('222.66.186.53',33812)嘗試連接中
legal_IP['180.160.22.100','222.66.186.53']
('222.66.186.53',33812)已經(jīng)成功連接
從33812接收到的信息是:tongji
從1143接收到的信息是:automobile
從1143接收到的信息是:tongji
從33812接收到的信息是:automobile
2)車載終端管理臺的驗證。
服務(wù)器端的操作為
請輸入您想要建立連接的端口號:18210
想要發(fā)送的指令是:shutdown
車載終端接收的消息為
從服務(wù)器接收到的指令:b'shutdown'
本次是通過車載終端將其從服務(wù)器接收到的信息再發(fā)回到服務(wù)器上顯示從而驗證了測試。
3)超時處理功能的驗證。
超過預(yù)定時間,服務(wù)器與車載終端主動斷開連接為
('58.41.201.173',18241)嘗試連接中
legal_IP['58.41.201.173']
('58.41.201.173', 18241)已經(jīng)成功連接
58.41.201.173:18241接收超時,即將斷開連接
58.41.201.173:18241已斷開連接!
1)基于Python中的SocketServer庫開發(fā)了一個非堵塞多線程的Socket服務(wù)器,詳細地介紹了設(shè)計和實現(xiàn)過程,主要核心點有BaseServer類、server_forever函數(shù)、select庫、BaseRequestHandle類,可以滿足汽車遠程車載監(jiān)控項目中多臺汽車車載終端和服務(wù)器數(shù)據(jù)傳輸?shù)幕竟δ堋?/p>
2)將互聯(lián)網(wǎng)中經(jīng)典的密碼驗證和IP黑名單等安全手段運用到燃料電池汽車遠程監(jiān)控中,對其設(shè)計和實現(xiàn)過程進行了詳細的介紹,主要核心點有verify_request函數(shù)和check_ip函數(shù),在一定程度上保障了服務(wù)器的通信安全。這為以后基于SocketServer的物聯(lián)網(wǎng)安全研究提供了參考。
3)車載終端管理臺的初步實現(xiàn),使用了Threading進行線程管理,獨立出一個線程進行socket有選擇地雙向連接,從而簡單有效地實現(xiàn)需要的功能,經(jīng)過測試,初步滿足項目功能,有待進一步完善。
4)為了驗證服務(wù)器功能,搭建了真實測試環(huán)境進行跟蹤測試,證明服務(wù)器功能的穩(wěn)定性和可靠性。
[1]《中國公路學(xué)報》編輯部. 中國汽車工程學(xué)術(shù)研究綜述·2017[J]. 中國公路學(xué)報,2017,30(6):1-197.
[2]武傳坤. 中國的物聯(lián)網(wǎng)安全:技術(shù)發(fā)展與政策建議[J]. 人民論壇·學(xué)術(shù)前沿,2016(17):47-58.
2018-06-19
1002-4581(2018)05-0001-05
U469.7
A
10.14175/j.issn.1002-4581.2018.05.001