系統的實現基于如下開發環境,如表1所示。
客戶端主要由連接模塊、數據庫模塊、任務管理模塊、狀態信息模塊、預覽模塊、錯誤處理模塊等組成。其中,客戶端自動重連機制的實現是非常關鍵的,系統設計了兩種情況將調用該機制:第一是客戶端啟動時,第二是網絡出現問題時。
(1)查詢數據庫,檢查是否有未完成任,如果沒有直接進行第(4)步;
(2)如果有未完成任務,將任務加入任務管理隊列;
(3)處理未完成任務,利用任務信息,向服務器端發送重連請求(RegUnfiCMD);根據任務對應的服務器IP地址,分別與對應服務器建立連接;值得注意的是,每個客戶端與每個服務器之間只有一條通道。發往同一服務器的后續任務直接利用已用通道,發送更新信息。

表1 開發環境
(4)啟動客戶端。
(1)客戶端在1分鐘后,查詢數據庫,讀取未完成任務,如果沒有,等待新的任務;
(2)如果有未完成任務,將任務加入任務管理隊列;
(3)處理未完成任務,從新與服務器進行連接請求,后續隊列的任務做相同的操作,但如果服務器與客戶端已經建立連接,后續任務不需要再發送建立連接請求;如果不能建立連接,轉到第(1)步。
當客戶端啟動時自動重連對應的偽代碼如下:

當服務器與客戶端網絡斷開后,調用定時器SetTimer(10,60000,NULL),則OnTimer(UINT nIDEvent)就會在1分鐘后激活進行重連請求。OnTimer實際上調用了客戶端啟動時的處理機制。由于系統是多對多模式,因此在服務器與客戶端網絡斷開后,客戶端與其他服務器的連接不會影響,只是處理斷開的服務器重連。
由于本系統采用基于安全通道的網絡機制,故實現客戶端連接模塊的代碼利用OpenSSL。
當有任務要上傳的時候,首先需要選擇可信的服務器,然后通過三次握手建立連接。
下面是對應的偽代碼:


只有通信雙方具有可信的證書,才能建立起連接。這樣就確保了通信雙方能夠在安全狀態下進行數據傳輸。
數據庫模塊是客戶端合理工作的保證,涉及任務管理、任務插入、任務查詢和任務刪除等。本系統利用開源ado2類對ACEESS數據庫進行讀寫操作。設計對數據操作的CDatebaseMannager類,該類涉及如下函數:
int OpenDatabase();打開數據庫
int CloseDatabase();關閉數據庫
int SelectSQL(CString strSQLCommand);查詢數據庫
int InsertSQL(CString strSQLCommand);插入數據庫
int UpdateSQL(CString strSQLCommand);更新數據庫
int DeleteSQL(CString strSQLCommand);刪除數據庫
int ExecuteProc(CStri ng strSQLCommand); 執行SQL語句
任務管理模塊主要負責任務的調度、任務上傳以及與服務器間的通信,是整個客戶端系統的靈魂。
實現的函數為handleUploadCmd,該函數是整個系統運行的保證,在函數內部設計任務文件的上傳、文件的壓縮以及文件狀態管理。
圖像預覽模塊利用CxImage類,可以對各類文件進行預覽,即任務文件在上傳之前,用戶可以對起預覽。
同 時, 可 以 設 計CPictrueView類對預覽文件進行放大、縮小等操作。
OpenTifFile函數負責對傳輸文件讀取預覽。
與此同時,系統還提供了GetFirstBitmapFromAvi函數,實現獲取并預覽avi文件第一幀圖像的功能。
類CStateShowDlg是狀態信息模塊,用于把任務實際運行狀態反饋給用戶,通過與任務管理模塊相結合,實時反映任務狀態。
其偽代碼如下:

更加詳細的任務狀態信息是基于任務內部的單個文件,系統中定義了如下結構體用于管理文 件 :FileUploadInfo、CurrentUploadStatus、UploadFileStatus等。除此之外,客戶端還有以下幾個類:CClientDlg是整個系統的框架;CDutyInitDlg主要負責任務初始化。
與數據庫通信部分的實現,主要涉及到部門信息的編輯、歷史任務的查詢以及任務對應文件的查詢。其過程如下:
第一,是部門信息的編輯,這部分主要是提供數據庫接口,方便添加、刪除、修改部門信息。
增加部門信息的實現函數為AddClinicInfoRecord函數,具體實現為:
同樣有關修改部門信息的實現為ModifyClinicInfoRecord函數,其具體實現方式,如圖1所示。

圖1 修改函數的具體實現
第二,是歷史任務查詢,通過給定的起止時間、查詢數據庫、返回所有滿足條件的人物信息,核心查詢函數為OnCheck函數,實現代碼如圖2所示。
第三,查詢任務對應文件信息主要對應兩個位置:其一是查詢歷史任務時,支持返回每個任務對應的文件;其二是任務狀態欄中任務對應的文件查詢功能。SQLFILE函數實現形式如圖3所示。

圖2 歷史任務查詢的具體實現

圖3 SQLFILE函數實現形式
服務器端主要實現如下模塊:啟動模塊、客戶端連接請求模塊、數據庫管理模塊、客戶端管理模塊、任務管理模塊、任務狀態及預覽模塊、任務接收模塊、文件解壓模塊。
啟動模塊是主要完成服務器啟動,打開監聽端口,同樣利用OpenSSL開放源碼。服務器啟動時,AfxBeginThr ead(ServerThread,this)實現網絡初始化,偽代碼如下:


服務器端數據庫管理模塊類似與客戶端,同樣也利用設計的CDatebaseMannager類 對ACCESS數據庫進行讀寫操作。服務器啟動時,同樣需要讀取未完成任務,并加入任務管理隊列,并等待客戶端發續傳請求進行激活。
客戶端管理模塊與任務管理模塊是服務器系統管理的主要對象。建立不同的數據結構進行管理。ListManagement用于任務管理,而ListServer用于管理客戶端。所有的待完成任務都由ListManagement進行管理,每個SSL對應一個客戶端IP地址。
任務狀態模塊,它同客戶端一樣。
客戶端先發起服務器請求,并與服務器建立SSL連接后,就可以與服務器進行通信。
發送新任務注冊SendDutyReg(SSL*ssl),更新未完成任務SendRegUnfinish(SSL* ssl,DutyInfo* dutyinfo)。對應接收服務器通信函數為HandleData(SSL * ssl),getNextUploadItem()函數在客戶端與服務器建立連接后,就持續工作,負責任務上傳的同步。
handleUploadCmd(char*m_pRecvData,SSL *ssl,int uploadflag)函數實現任務上傳,該函數中涉及文件壓縮、狀態信息反饋、任務調度等。
一個任務實際上由一個或多個文件組成,因此任務上傳主要完成對文件的上傳。
任務上傳的狀態見表2所示,這些狀態同時也會反饋給客戶端用戶。
服務器與客戶端通信實現:服務器根據任務隊列,調用getNextUploadItem函數,發送針對某個任務的UploadCMD請求給客戶端。客戶端HandleData函數接收到UploadCMD命令,調用handleUploadCmd處理該任務對應文件的上傳。

表2 任務上傳狀態