李 瑋,董淵科
(1.西北工業(yè)大學(xué) 軟件與微電子學(xué)院,陜西 西安 710072;2.西北工業(yè)大學(xué) 航海學(xué)院,陜西 西安 710072)
隨著ETX、SPT2C、ATPPC等嵌入式模塊的規(guī)?;a(chǎn),設(shè)計(jì)技術(shù)的成熟,對(duì)這些模塊的驗(yàn)收測試、仿真與其交聯(lián)的模塊、驗(yàn)證其功能、性能及接口的工作也越來越頻繁?,F(xiàn)代自動(dòng)測試系統(tǒng)是由多個(gè)分系統(tǒng)組成的,每個(gè)分系統(tǒng)由通用系統(tǒng)或?qū)S孟到y(tǒng)實(shí)現(xiàn),并承擔(dān)一部分相對(duì)獨(dú)立的測控任務(wù),各分系統(tǒng)之間通過信息交換實(shí)現(xiàn)并行與協(xié)同工作,共同實(shí)現(xiàn)整個(gè)自動(dòng)測試系統(tǒng)的功能[1]。提出一種采用客戶機(jī)/服務(wù)器模式的測試系統(tǒng)。該系統(tǒng)讓每個(gè)客戶機(jī)負(fù)責(zé)在本地對(duì)嵌入式模塊的接口進(jìn)行測試,而服務(wù)器負(fù)責(zé)各項(xiàng)測試命令的發(fā)送以及結(jié)果的接收和顯示,這樣可使測試部分和控制部分分離,便于模塊化設(shè)計(jì),提高整個(gè)測試系統(tǒng)的運(yùn)行效率。
測試系統(tǒng)分為測試平臺(tái)和控制平臺(tái)2部分,控制平臺(tái)相當(dāng)于服務(wù)器,負(fù)責(zé)測試命令的發(fā)送。測試平臺(tái)用于對(duì)嵌入式模塊接口進(jìn)行本地測試,它啟動(dòng)后必須連接到控制平臺(tái)獲得測試的相關(guān)信息后方可進(jìn)行測試。對(duì)于測試平臺(tái)的主體部分,測試人員可以根據(jù)被測對(duì)象使用不同的語言和方式進(jìn)行設(shè)計(jì),可以不局限于使用與控制平臺(tái)相同的語言,這也是采用C/S模式的優(yōu)勢。測試臺(tái)-控制臺(tái)通信流程如圖1所示。
在各模塊交聯(lián)測試中,測試的命令與結(jié)果數(shù)據(jù)量一般都很小,往往測試平臺(tái)反饋給控制平臺(tái)的結(jié)果只有正常/異常,或者一些簡略的異常信息,但是也有一些測試平臺(tái)需要將一些大容量的文件信息發(fā)送給控制平臺(tái)進(jìn)行存儲(chǔ)并顯示,在此,以小數(shù)據(jù)量的通信來設(shè)計(jì)網(wǎng)絡(luò)傳輸中的數(shù)據(jù)包格式。
測試系統(tǒng)的網(wǎng)絡(luò)通信是基于TCP/IP協(xié)議的。選用TCP/IP協(xié)議是因?yàn)樗诨镜腎P數(shù)據(jù)包上增加了可靠性和流量控制,其流式套接字定義了一種可靠的面向連接的服務(wù),實(shí)現(xiàn)了無差錯(cuò)無重復(fù)的順序數(shù)據(jù)傳輸[2]。
1.2.1 通信協(xié)議
測試系統(tǒng)通過發(fā)送一定格式的數(shù)據(jù)包來實(shí)現(xiàn)網(wǎng)絡(luò)通信。一次發(fā)送和接收命令信息的緩沖區(qū)大小為1 024字節(jié),一次通信過程(發(fā)送/接收)只能包含一個(gè)命令或結(jié)果。具體協(xié)議的格式為:狀態(tài)字段+數(shù)據(jù)長度字段+命令字段+數(shù)據(jù)字段。信息結(jié)構(gòu)格式見表1。
表1 命令信息結(jié)構(gòu)表Tab.1 Structure of command packet
在此還需注意的是,控制平臺(tái)和測試平臺(tái)在開發(fā)過程中可能是用不同的開發(fā)環(huán)境或不同的編程語言,由此而產(chǎn)生相同的數(shù)據(jù)類型可能所占的字節(jié)數(shù)不同,雙方需要約定數(shù)據(jù)包中各字段的數(shù)據(jù)存放方式與所代表的數(shù)據(jù)類型。同時(shí)可以根據(jù)具體調(diào)試臺(tái)系統(tǒng)的需要設(shè)計(jì)不同的命令字段和狀態(tài)字段編碼。
1.2.2 CAsyncSocket特性分析
CAsyncSocket提供全面的由事件驅(qū)動(dòng)的Socket通信能力,應(yīng)用程序要響應(yīng)Windows Socket激發(fā)的事件,就要?jiǎng)?chuàng)建自己派生的Socket子類捕獲和響應(yīng)事件[3]。由于CAsyncSocket是虛擬了一個(gè)消息池,借助它來完成各部分的消息循環(huán),所有的操作必須在一個(gè)線程里完成才可以,其本身是異步的,已經(jīng)設(shè)置了類似于多線程的機(jī)制。因此在使用CAsyncSocket實(shí)現(xiàn)網(wǎng)絡(luò)通信時(shí),不需要使用多線程技術(shù),只要將CAsyncSocket與MFC的消息響應(yīng)機(jī)制進(jìn)行有效地結(jié)合,就可以提高網(wǎng)絡(luò)通信的處理效率。
為了說明問題,建立一個(gè)會(huì)話程序的例子,控制平臺(tái)和測試平臺(tái)分別獨(dú)立編程。因?yàn)樵诠こ讨锌刂破脚_(tái)除了進(jìn)行網(wǎng)絡(luò)通信可能還負(fù)擔(dān)有別的功能,所以本例中控制平臺(tái)被建立為單文檔MFC應(yīng)用程序ServerProject,使用向?qū)?,選擇支持WinSock;測試平臺(tái)被建立為基于對(duì)話框的MFC應(yīng)用程序ClientProject,使用向?qū)桑x擇支持 WinSock。在控制平臺(tái)和測試平臺(tái)都自定義派生于CAsyncSocket類的CMySocket類。
從軟件設(shè)計(jì)一致性的角度,關(guān)于socket的全部處理都使用MFC消息響應(yīng)機(jī)制,所以在控制平臺(tái)和測試平臺(tái)都需要構(gòu)造以下4類消息[4]:
1)WM_MY_INITSOCKET 消息,初始化 Socket;
2)WM_MY_MESSAGE消息,發(fā)送 Socket數(shù)據(jù);
3)WM_MY_RECEIVE消息,接收來自Socket的數(shù)據(jù);
4)WM_MY_CLOSE消息,接收Socket連接斷開的事件。
以上消息分別對(duì)應(yīng)于 OnMyInitial (),OnMyMessage(),OnMyReceive(),OnMyClose()等函數(shù)。
在實(shí)際工程中,控制平臺(tái)的應(yīng)用程序往往會(huì)有多個(gè)對(duì)話框,網(wǎng)絡(luò)通信的結(jié)果也需要在多個(gè)對(duì)話框中傳遞,經(jīng)過實(shí)驗(yàn),在ServerProjectView類中生成并調(diào)用CMySocket類的對(duì)象是一種可靠的方法。
在ServerProjectView類中需要一個(gè)新的消息WM_MY_ACCEPT,用于處理Socket的OnAccept函數(shù)[5],它所對(duì)應(yīng)的函數(shù)為OnMyAccept()。在ServerProjectView.cpp中聲明全局變量m_listenSocket用于控制平臺(tái)監(jiān)聽連接請(qǐng)求,m_connectSocket用于處理連接Socket。ServerProjectView類的工作過程如下:
1)應(yīng)用程序啟動(dòng)時(shí),響應(yīng)WM_MY_INITSOCKET消息,在OnMyInitial()函數(shù)中初始化全局變量,調(diào)用Create函數(shù)將端口號(hào)與控制平臺(tái)本地IP地址綁定于m_listenSocket變量,調(diào)用Listen()函數(shù),使m_listenSocket變量處于監(jiān)聽狀態(tài);
2)測試平臺(tái)啟動(dòng)并發(fā)起連接請(qǐng)求后,響應(yīng)WM_MY_ACCEPT消息,完成Socket連接;
3)測試人員根據(jù)相關(guān)界面進(jìn)行操作,確定要發(fā)送的測試命令后,響應(yīng)WM_MY_MESSAGE消息,調(diào)用Send函數(shù)將這些測試命令數(shù)據(jù)包發(fā)送給測試平臺(tái);
4)Socket接收到測試結(jié)果后,響應(yīng)WM_MY_RECEIVE消息,解析所得數(shù)據(jù)獲得結(jié)果。
在CMySocket類中需要聲明常量MAX_MSG_PACKET為1 024,還需要聲明如下變量:
1)BYTE m_nBuffer[MAX_MSG_PACKET+1];//m_nBuffer為類的數(shù)據(jù)緩沖區(qū)
2)UINT m_nLength;//m_nLength為緩沖區(qū)大小值
3)CView*pView;//視類指針
CMySocket類的工作過程如下:
1)函數(shù) bool CMySocket::GetView()獲取應(yīng)用程序視類指針,并賦值給pView;
2)函數(shù) void CMySocket::OnAccept(int nErrorCode)接收到連接請(qǐng)求,處理FD_ACCEPT事件,通過視類指針發(fā)送WM_MY_ACCEPT消息;
3)函數(shù) void CMySocket::OnReceive(int nErrorCode)處理FD_READ事件,通過視類指針發(fā)送WM_MY_RECEIVE消息,將數(shù)據(jù)緩沖區(qū)接收到的數(shù)據(jù)發(fā)送給ServerProjectView類。
測試平臺(tái)為一個(gè)基于對(duì)話框的應(yīng)用程序ClientProject,在ClientProjectDlg類中生成并調(diào)用CMySocket類的對(duì)象。
在ClientProjectDlg中聲明全局變量m_clientSocket用于與控制平臺(tái)進(jìn)行網(wǎng)絡(luò)通信。ClientProjectDlg類的工作過程如下:
1)應(yīng)用程序啟動(dòng)時(shí),響應(yīng)WM_MY_INITSOCKET消息,在OnMyInitial()函數(shù)中初始化全局變量,調(diào)用Create函數(shù),無需指定端口號(hào),但必須指定控制平臺(tái)的IP地址serverIP,因?yàn)镃reate函數(shù)中觸發(fā)了FD_CONNECT事件,m_clientSocket會(huì)自動(dòng)向控制平臺(tái)發(fā)起連接請(qǐng)求;
2)Socket接收到測試命令后,響應(yīng) WM_MY_RECEIVE消息,解析所得數(shù)據(jù)獲得命令;
3)執(zhí)行完成測試命令并得到測試結(jié)果后,根據(jù)協(xié)議將數(shù)據(jù)構(gòu)造測試結(jié)果數(shù)據(jù)包,響應(yīng)WM_MY_MESSAGE消息,調(diào)用Send函數(shù)將這些測試結(jié)果數(shù)據(jù)包發(fā)送給控制平臺(tái)。
在CMySocket類中需要聲明常量MAX_MSG_PACKET為1 024,需要聲明如下變量:
1)YTE m_nBuffer[MAX_MSG_PACKET+1];//m_nBuffer 為類的數(shù)據(jù)緩沖區(qū)
2)INT m_nLength;//m_nLength為緩沖區(qū)大小值
3)ClientProjectDlg*pMyDialog;//對(duì)話框類指針
CMySocket類的工作過程如下:
1)函數(shù) bool CMySocket::GetDlg()獲取應(yīng)用程序?qū)υ捒蝾愔羔?,并賦值給pMyDialog;
2)函數(shù) void CMySocket::OnReceive(int nErrorCode)處理FD_READ事件,通過視類指針發(fā)送WM_MY_RECEIVE消息,將數(shù)據(jù)緩沖區(qū)接收到的數(shù)據(jù)發(fā)送給ClientProjectDlg類。
作為基于網(wǎng)絡(luò)通信的測試系統(tǒng),應(yīng)具有最大的可擴(kuò)展性和高穩(wěn)定性[6]。由于TCP/IP協(xié)議采用3次握手建立連接,提供可靠的數(shù)據(jù)流服務(wù),可以保證其基礎(chǔ)上所搭建的測試系統(tǒng)的高穩(wěn)定性。在項(xiàng)目測試實(shí)驗(yàn)過程中,網(wǎng)絡(luò)通信達(dá)到無誤碼率,滿足嵌入式模塊接口測試對(duì)結(jié)果準(zhǔn)確性的需求。
該網(wǎng)絡(luò)通信技術(shù)應(yīng)用于地圖嵌入式模塊測試及語音嵌入式模塊測試。其中前者需要進(jìn)行命令通信,而后者既需要傳輸命令,又需要傳輸大批量的語音文件。此時(shí)專用通信協(xié)議表現(xiàn)出良好的可移植性,通過對(duì)命令信息結(jié)構(gòu)的數(shù)據(jù)字段的擴(kuò)展,實(shí)現(xiàn)語音文件的可靠和高速傳輸。
在設(shè)計(jì)過程中,異常處理是影響系統(tǒng)穩(wěn)定性的關(guān)鍵。當(dāng)網(wǎng)絡(luò)電纜被拔出、測試臺(tái)程序或控制臺(tái)程序被強(qiáng)制關(guān)閉時(shí),需要及時(shí)被發(fā)現(xiàn)并處理。因此,在控制臺(tái)設(shè)置定時(shí)器,周期查詢連接是否正常,結(jié)合WM_MY_CLOSE消息的接收情況,對(duì)異常情況進(jìn)行有效識(shí)別并處理。
提出了一種針對(duì)嵌入式模塊接口性能測試系統(tǒng)的網(wǎng)絡(luò)通信方式,使用了Visual C++6.0 MFC平臺(tái),主要運(yùn)用了MFC封裝的CAsyncSocket類的相關(guān)特性,并將之與MFC具有的消息響應(yīng)機(jī)制結(jié)合,通過引入自定義的通信協(xié)議,達(dá)到快速穩(wěn)定的通信效果。所有代碼均來源于自動(dòng)化測試軟件的實(shí)際工程中,在Visual C++6.0平臺(tái)下調(diào)試通過。
[1]張?jiān)?,韓燮.網(wǎng)絡(luò)化測試系統(tǒng)中問件的研究與設(shè)計(jì)[J].計(jì)算機(jī)工程與設(shè)計(jì),2009,30(22):5279-5283.ZHANG Yuan,HAN Xie.Research and design of middleware in network test system[J].Computer Engineering and Design,2009,30(22):5279-5283.
[2]李峰,陳向益.TCP/IP—協(xié)議分析與應(yīng)用編程[M].北京:人民郵電出版社,2008.
[3]李文天,董祥軍,張潔.用MFC CAsyncSocket類實(shí)現(xiàn)計(jì)算機(jī)間的通信[J].山東輕工業(yè)學(xué)院學(xué)報(bào),2001,15(1):21-25.LI Wen-tian,DONG Xiang-jun,ZHANG Jie.Realizing the computer communication by using MFC CAsyncSocket class[J].Journal of Shandong Institute of Light Industry,2001,15(1):21-25.
[4]曾小立.基于TCP/IP的數(shù)據(jù)遠(yuǎn)程傳輸?shù)膶?shí)現(xiàn)[J].三峽大學(xué)學(xué)報(bào):自然科學(xué)版,2002(24):432-433.ZENG Xiao-li.The implementation of the data-transmission based on TCP/IP[J].Jounal of China Three Gorges University:Natural Science,2002(24):432-433.
[5]羅瑜,胡榮強(qiáng).遠(yuǎn)程監(jiān)控系統(tǒng)中網(wǎng)絡(luò)通信的研究與實(shí)現(xiàn)[D].武漢:武漢理工大學(xué),2006.
[6]王瑞斌,李鳳崎,施玉勛,等.基于IOCP機(jī)制的網(wǎng)絡(luò)游戲服務(wù)器通信層的實(shí)現(xiàn)[J].計(jì)算機(jī)工程與應(yīng)用,2009,45(7):75-78 WANG Rui-bin,LI Feng-qi,SHI Yu-xun,et al.Realization of IOCP-based net layer of online games server[J].Computer Engineering and Applications,2009,45(7):75-78.