王璇 王亮 楊玻 中國航空工業(yè)集團公司西安航空計算技術(shù)研究所
隨著網(wǎng)絡(luò)通信在航空領(lǐng)域使用日趨廣泛,我們對于高可靠的網(wǎng)絡(luò)通信要求也是越來越高。因此操作系統(tǒng)中網(wǎng)絡(luò)的支持程度就顯得尤為重要。在現(xiàn)行眾多的操作系統(tǒng)中,Linux支持多用戶、多進程、多線程,實時性好,功能強大且穩(wěn)定。在通信和網(wǎng)絡(luò)功能方面,Linux優(yōu)于其它操作系統(tǒng)。其它操作系統(tǒng)不包含如此緊密的內(nèi)核結(jié)合在一起的聯(lián)接網(wǎng)絡(luò)的能力,也沒有內(nèi)置這些聯(lián)網(wǎng)特性的靈活性。而Linux為用戶提供了完善的、強大的網(wǎng)絡(luò)功能。
Socket作為UNIX的進程通信機制,通常也稱作“套接字”,用于描述IP地址和端口號,是一個通信鏈的句柄,可以用來實現(xiàn)不同虛擬機或不同計算機之間的通信。套接字通過調(diào)用系統(tǒng)提供的庫函數(shù)實現(xiàn)數(shù)據(jù)傳輸,不需要過多了解底層的細(xì)節(jié),從而完成設(shè)備和網(wǎng)絡(luò)之間的通信。
Socket編程過程分為服務(wù)器端和客戶端編程,通信過程如圖1所示。
圖1 服務(wù)器端和客戶端Socket通信過程
Linux環(huán)境下的Socket編程是通過套接字的相關(guān)接口來實現(xiàn)的,應(yīng)用程序可以通過Socket接口來收發(fā)數(shù)據(jù)。通信過程如下:
首先創(chuàng)建套接字socket(),然后服務(wù)器端綁定套接字bind(),即將本地主機的IP地址、端口號與創(chuàng)建的套接字相綁定。綁定完成后,服務(wù)器端監(jiān)聽listen(),等待客戶端連接??蛻舳税l(fā)送連接請求connect()??蛻舳说恼埱髸|發(fā)服務(wù)器端和客戶端底層的三次握手,服務(wù)器端接受連接accept()。成功建立連接后,雙方就可以進行數(shù)據(jù)收發(fā)了。一般使用send()發(fā)送數(shù)據(jù),使用recv()來接收數(shù)據(jù)。以上,Socket就連接了客戶端和服務(wù)器端的應(yīng)用程序。在雙方不需要通信時,可以使用close()關(guān)閉連接。
上面介紹了Socket的網(wǎng)絡(luò)通信原理,現(xiàn)在我們就可以對數(shù)據(jù)傳輸軟件進行設(shè)計了。這是一個運行在Linux操作系統(tǒng)上基于Socket的客戶端程序,我們主要從軟件概述、Linux定時器使用、連接保持模塊、數(shù)據(jù)發(fā)送模塊和數(shù)據(jù)接收模塊等5個方面進行闡述。
本軟件運行在一個裝有Ubuntu Linux操作系統(tǒng)的航空設(shè)備上。該設(shè)備通過網(wǎng)線與數(shù)據(jù)庫服務(wù)器相連接,并將設(shè)備和服務(wù)器的IP地址設(shè)置在同一網(wǎng)段中。在客戶端與服務(wù)器端建立連接后,客戶端主動向服務(wù)器端請求上層應(yīng)用軟件所需要的數(shù)據(jù),服務(wù)器端接收到指令后找到相應(yīng)數(shù)據(jù)返回給客戶端,供上層應(yīng)用使用。由于上層應(yīng)用隨時可能下發(fā)數(shù)據(jù)傳輸請求,故客戶端應(yīng)周期性判斷與服務(wù)器端的連接狀態(tài),保證在上層應(yīng)用下發(fā)命令時客戶端和服務(wù)器端是通信正常的。
Linux系統(tǒng)提供了毫秒級定時器itimerval,它是一個有兩個成員變量it_value和it_interval的結(jié)構(gòu)體。it_value指定時器安裝后首次啟動的初始值,it_interval指定時器重啟動的間隔值。本軟件將它們都設(shè)置為1秒,即定時器啟動后將會以1秒為間隔周期觸發(fā)。接著使用setitimer()函數(shù)使方才設(shè)置的定時器生效,并使用signal()將中斷處理函數(shù)掛接入該定時器。這樣,系統(tǒng)每秒就能運行一次中斷處理函數(shù),它包含連接保持模塊、數(shù)據(jù)發(fā)送模塊和數(shù)據(jù)接收模塊。
客戶端在Socket初始化完成后,會周期調(diào)用connect()與服務(wù)器端嘗試建立連接,如果建立連接成功,則會給服務(wù)器端發(fā)送連接保持命令字,如果在超時時間內(nèi)服務(wù)器返回了相應(yīng)命令字,說明連接保持。這時,上層應(yīng)用就可以下發(fā)傳輸數(shù)據(jù)的命令了;如果連續(xù)三個周期服務(wù)器沒有在超時時間內(nèi)回應(yīng)命令字,則判定服務(wù)器下線,斷開并關(guān)閉其連接。下個周期繼續(xù)調(diào)用connect()嘗試與其建立連接。
在連接保持的狀態(tài)下,當(dāng)上層應(yīng)用下發(fā)數(shù)據(jù)傳輸命令,客戶端就可以使用send()函數(shù)來發(fā)送數(shù)據(jù)了。如果出現(xiàn)了小于發(fā)送長度的情況,就代表著數(shù)據(jù)有部分沒有發(fā)送完成,只是發(fā)送了一部分,這時就需要再次發(fā)送來完成數(shù)據(jù)發(fā)送。
當(dāng)服務(wù)器端接收到客戶端所請求的數(shù)據(jù)時,服務(wù)器端就會回復(fù)數(shù)據(jù),即客戶端使用recv()接收數(shù)據(jù)。由于服務(wù)器端不一定會立即回復(fù)數(shù)據(jù),所以要設(shè)置超時時間。在超時時間內(nèi),客戶端接收到了足夠數(shù)量的數(shù)據(jù),并進行累加和校驗,校驗成功,那么傳遞給上層應(yīng)用;校驗失敗,則通知服務(wù)器端重傳。如果服務(wù)器端回復(fù)超時,則也需要服務(wù)器端重傳。
程序采用C語言編寫,編譯Linux客戶端時需要執(zhí)行如下編譯命令:gcc -o client client.c,然后運行此執(zhí)行文件,命令如下:
在Linux系統(tǒng)下執(zhí)行完上述命令后,設(shè)備就和數(shù)據(jù)庫服務(wù)器建立連接了。設(shè)備先向服務(wù)器發(fā)送請求數(shù)據(jù)命令,再接收服務(wù)器發(fā)來的數(shù)據(jù),是典型的“主從模式”一發(fā)一收。
Linux網(wǎng)絡(luò)具有較高的安全性,可以進行網(wǎng)絡(luò)資源的共享,完成網(wǎng)絡(luò)通信。它還包含著很多網(wǎng)絡(luò)協(xié)議,擁有開放的源代碼,我們可以利用Linux網(wǎng)絡(luò)進行基于Socket的網(wǎng)絡(luò)通信技術(shù)的開發(fā)。Socket作為其中的接口起著舉足輕重的作用,連接起了網(wǎng)絡(luò)設(shè)備和應(yīng)用程序與下層協(xié)定,從而完成設(shè)備和網(wǎng)絡(luò)之間的網(wǎng)路通信。