樹愛兵,徐 棱,張雷元
交通信號控制系統作為城市交通管理系統的一個重要子系統,能夠實時調整控制區域內的信號配時方案,均衡路網交通流運行,使停車次數、延誤時間及環境污染等減至最小,充分發揮道路系統的交通效益,從而保證城市交通干線乃至整個城市交通路網的暢通、安全、高效運行[1]。通信服務器作為交通信號控制系統的重要組成部分,負責與路口信號機、用戶監控終端及控制軟件的數據通信及處理。通訊服務器必須能夠保證長時間的為大量的信號機及終端軟件提供信息通訊服務,因此,對于交通信號控制系統,經常遇到的問題就是通信服務器的多客戶瓶頸問題,如何設計同時服務多個客戶端,同時性能又比較高的通訊服務器,對于解決交通信號控制系統的性能和容量瓶頸問題勢在必行。
Winsock 2.0引入的內核級高效處理機制IOCP(完成端口)是處理大量并發連接的最佳處理方案[2],相對于其他I/O模型,IOCP提供了較好的伸縮性和較高的數據吞吐率,能夠滿足通信服務器高性能的要求。本文基于IOCP機制設計了一種高性能的通信服務器,通過對其性能方面進行優化,極大地提高了交通信號控制系統通信服務器的性能和穩定性。
交通信號控制系統主要由三層結構組成[3]:路口設備層,通信服務器層,監控終端層,如圖1所示:
在整個系統中,路口設備層、通信服務器層、監控終端層中,通信服務器程序扮演著“代理”的角色,一方面接受來自路口設備的實時運行信息,并轉發給監控終端層軟件,另一方面接受來自用戶終端的控制命令,并轉發給路口層設備。

圖1 交通信號控制系統結構
IOCP模型是微軟提供的用于異步處理各種I/O設備的一種機制,除了套接字句柄之外,還可接受其它東西。完成端口模型創建一個Windows完成端口對象,該對象通過一定數量的線程對重疊I/O請求進行管理,以便對已經完成的重疊I/O請求提供服務。IOCP模型,如圖2所示:

圖2 I OCP模型圖
完成端口對象可以看作為一個系統維護的I/O完成隊列,操作系統把已經完成的重疊I/O請求的通知放入其中,利用事先創建好的若干個工作者線程逐一從消息隊列中取出消息并加以處理,它可以為任何用戶的任何I/O 操作服務。完成端口是使用線程池的一種機制,只需少數幾個線程就可以處理大量的I/O請求,避免CPU花費大量的時間在線程的調度上,提高了資源的利用率[4]。
交通信號控制系統通信服務器的核心功能,是將前端路口設備的信息發送給監控終端軟件,并接受監控終端的命令,轉發至路口設備執行。因此,在網絡傳輸中,保證通信數據的快速性、準確性、可靠性是整個系統的關鍵。系統采用面向連接的TCP網絡傳輸層協議,該協議具有擁塞回避機制以及超時和差錯重傳機制,確保了數據在傳輸中的流暢、完整和正確。
1) 客戶上下文信息結構
服務器監聽線程在接受客戶端連接時,將給其分配一個描述客戶上下文信息的結構,一般包括客戶端的套接字以及與該套接字相關的讀寫緩沖區等信息。具體結構定義如下:


2) 擴展的OVERLAPPED結構
當使用GetQueuedCompletionStaus函數檢查消息隊列時,其自身的OVERLAPPED 結構所表示的數據還不能滿足傳遞數據的要求,應用程序不能確定完成的是哪個操作,因此,需在此基礎上進行擴展,具體結構定義如下:

通過該擴展結構把重疊結構體的地址參數傳遞給異步I/O函數。該結構中的nSequencNumber參數和ClientSocketContext結構中的參數nCurrentSendSequence Number和nCurrentReadSequenceNumber是為了解決數據包中可能不按照正確順序讀寫而設計的。
采用IOCP模型編寫服務器程序主要包括兩種類型的線程[5]:主線程和工作線程。主線程負責創建并監聽套接字,創建工作線程,等待并接受客戶端的連接,并將其關聯到IOCP等。而工作線程則負責等待并處理在IOCP 對象上完成的事件。
IOCP通訊服務器工作流程,如圖3所示:

圖3 ICOP通訊服務器總體流程
圖中實線由通信服務器程序完成,虛線由Windows操作系統進行處理, 不需要程序進行干預。
在采用 IOCP機制實現交通信號控制系統通信服務器時,會遇到許多棘手的問題[6][7],本文就其中3個關鍵問題進行討論。
3.3.1 數據包重排序
IOCP通信服務程序使用多個工作線程來實現高性能和高并發性,因此異步I/O請求的線程與異步處理I/O完成的線程可能不是同一個線程,工作者線程的完成順序是不確定的,也就是說先完成異步I/O的不一定先處理。當你通過投遞發送請求到IOCP來發送數據時,待發送數據也被重新排序了。針對該問題,通過在緩沖類中增加讀寫順序號,并按照順序號來處理內存,如果順序號相同,那么這個數據就可以進行處理,否則,需要將不正確順序號的數據包進行緩存,直到之前的數據包處理完后才可以處理它。
3.3.2 異步讀取和數據包處理
交通信號控制系統前端信號機在和中心通信服務軟件通信時,按照預先定義的應用層協議進行數據通訊,每個數據表由消息頭和消息數據組成,在消息頭中定義了當前數據表的大小,標識等信息,接收方通過讀取消息頭得到該數據長度,從而來判斷是否讀數據表完成。由于IOCP 采用異步讀操作,因此在同一個時間段內,接受到的數據包中可能包含一個或多個數據表,或者數據表的一部分。假設共有 3個數據包,這3個數據包中含有4個數據表,如圖4所示:

圖4 數據包和數據表
因此需編寫專門的數據包解析函數,來獲得完整的數據表。如果數據表完整,則解析出這個數據表進行相關處理,如果數據表不完整,則必須將其中不完整的數據表進行緩存,直到下一個順序號數據表的到來,把先前緩存的數據和剛新接受的數據進行拼接,從而組成一個新的數據包,再進行解析。
3.3.3 無效的客戶端連接
當前端路口信號機出現壞鏈接時,即路口設備和中心通信服務器建立 Socket連接后,既不發送數據,也不關閉連接,就會造成 Accept函數投遞的大量重疊操作不能返回,此時通信服務器為了接受其它前端路口信號機的鏈接請求,需要投遞更多接受I/O,占用大量的系統資源。為了避免此類事件的發生,通信服務器采用網絡心跳檢測包來解決這個問題,服務器每15秒向所有建立 Socket 連接的客戶端信號機發送網絡心跳檢測包,客戶端信號機在收到心跳檢測包后,回送一個對應的網絡心跳檢測包,表明發送方仍然處于工作狀態。如果客戶端信號機連續3個心跳檢測包都沒有回應,此時通信服務器將關閉和此客戶信號機的連接。
網絡心跳檢測包同樣適用于檢測通信雙方是否非正常退出[8],如果在規定的時候內對方沒有響應的話,通信的另一方就可以根據情況采取相應的措施。
基于以上設計思路建立系統軟件,我們通過仿真信號機軟件作為客戶端,搭建仿真測試平臺,對交通信號控制系統通訊服務器進行測試。
1) 系統硬件環境:服務端采用IBM服務器,雙核CPU 2.13GHz,4G內存;客戶端為4臺臺式機,Pentium (R) 4 CPU 2GHZ,1G內存。
2) 網絡環境:100M局域網絡。
3) 系統平臺環境:服務器操作系統為 Microsoft Windows 2003 Server,客戶端操作系統為Windows XP。
1) 測試軟件:基于IOCP編寫信號機客戶端仿真軟件,每臺客戶臺式機上運行500個客戶端軟件,同時連接服務端軟件。
2) 測試數據:信號機客戶端仿真軟件每2秒發送一條隨機的檢測器數據,同時不定時地發送信號機當前運行方案、信號相位、周期及心跳檢測包等數據。
經測試驗證,當通訊服務器同時連接2000個客戶端連接時,CPU占用率平均穩定在 40%左右,其中每個路口信號機與服務器為一個連接,由于IOCP維護了一個先進先出的消息隊列來處理服務,沒有出現客戶端信號機軟件得不到服務的情況。測試結果表明:利用IOCP機制實現的通信服務器能夠針對大量的客戶請求進行高效處理,系統能夠同時監控大量路口信號機的運行狀態、檢測器流量數據等任務,在速度和性能上體現出良好的特性,達到了系統設計的預期要求。
根據本文論述方法所設計的通信服務器,已經在多個城市交通信號控制工程得用應用,取得了良好的實施效果。
[1]楊佩昆,吳兵.交通管理與控制.[M]北京:人民交通出版社,2003.
[2]Anthony Jones、Jim Ohlund,Network Programming for Microsoft Windows,2nd Edition,[M]北京:清華大學出版社,2002
[3]樹愛兵、苑雷、趙永進,城市交通信號干線協調控制系統研究,[j]中國交通信息產業,2009.1
[4]吳永明、何迪,基于完成端口的服務器底層通信模塊設計,[j]信息技術,2007.3
[5]杜翔雷、躍明,基于IOCP 的服務器端應用程序,[j]計算機系統應用,2009.02
[6]Amin Gholiha,A simple IOCP server/client class,http://www.codeproject.com/KB/IP/ iocp_server_client.aspx,2008.12
[7]陳懷松、陳家琪,IOCP寫服務程序時的關鍵問題研究,[j]計算機工程與設計,2010.17
[8]費紹敏、龔曉峰、盧海峰、袁潔,基于IOCP 的新聞交換平臺的設計與實現,[j]控制管理,2009.4