• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

      Linux下基于TCP傳輸組件的實現(xiàn)

      2014-01-01 03:09:48苑曉芳劉志廣
      無線電通信技術(shù) 2014年4期
      關(guān)鍵詞:接收數(shù)據(jù)發(fā)送數(shù)據(jù)服務(wù)端

      苑曉芳,劉志廣

      (中國電子科技集團(tuán)公司第五十四研究所,河北石家莊050081)

      0 引言

      隨著國產(chǎn)Linux操作系統(tǒng)的不斷應(yīng)用,原來在Windows平臺下的信息系統(tǒng)也逐漸轉(zhuǎn)向了Linux平臺。在信息系統(tǒng)中非常重要的一個部分就是數(shù)據(jù)的共享,該功能通常由數(shù)據(jù)流轉(zhuǎn)軟件實現(xiàn),而數(shù)據(jù)傳輸部分是該軟件一個重要的底層功能支撐。根據(jù)對組件的多客戶并發(fā)應(yīng)用、保證數(shù)據(jù)傳輸?shù)目煽啃院蜁r效性的要求特點,設(shè)計實現(xiàn)了一個在Linux系統(tǒng)下基于TCP協(xié)議的傳輸組件。

      1 傳輸組件的工作原理

      1.1 服務(wù)和客戶的初始化

      傳輸組件是一個對等傳輸,所以在使用時,要先初始化本地的傳輸服務(wù)端和客戶端。

      (1)初始化組件服務(wù)端

      建立組件服務(wù)端的套接字,對其進(jìn)行參數(shù)設(shè)置,然后將本地服務(wù)端口號綁定到套接字。

      啟動監(jiān)聽線程:該線程是為等待接收新客戶端的連接請求。

      啟動接收線程:該線程是為接收已連接客戶端發(fā)送的數(shù)據(jù)。

      (2)初始化組件客戶端

      啟動發(fā)送線程:該應(yīng)用線程是為處理客戶端提交發(fā)送的數(shù)據(jù)。

      1.2 數(shù)據(jù)傳輸

      (1)數(shù)據(jù)發(fā)送接收的準(zhǔn)備過程

      數(shù)據(jù)流轉(zhuǎn)軟件調(diào)用組件發(fā)送接口進(jìn)行數(shù)據(jù)發(fā)送。組件客戶端首先調(diào)用socket()函數(shù)創(chuàng)建新的通信套接字,通過connect()函數(shù)和目的地址服務(wù)端建立連接。連接建立成功后,向服務(wù)端發(fā)送本地的監(jiān)聽服務(wù)端口號??蛻舳藢⒔⒊晒Φ倪B接套接字存放到套接字列表。建立新的發(fā)送數(shù)據(jù)結(jié)構(gòu),將待發(fā)送內(nèi)容和數(shù)據(jù)類型添加到結(jié)構(gòu)中,并將該數(shù)據(jù)結(jié)構(gòu)添加到待發(fā)送數(shù)據(jù)列表。

      服務(wù)端在監(jiān)聽端口調(diào)用accept()函數(shù)成功后,返回一個新的套接字表示與客戶端的連接。調(diào)用recv()函數(shù)接收客戶端發(fā)來的服務(wù)端口號。將返回的套接字和操作實例用map表進(jìn)行保存,并將返回的套接字保存到套接字列表中。

      客戶端發(fā)送線程通過select()函數(shù),遍歷發(fā)送套接字列表,查找出已提交數(shù)據(jù)的套接字,然后從線程池取出線程用于對該目的地址進(jìn)行數(shù)據(jù)發(fā)送。

      (2)數(shù)據(jù)發(fā)送接收的具體過程

      首先從發(fā)送數(shù)據(jù)列表中取出待發(fā)送數(shù)據(jù),將當(dāng)前發(fā)送狀態(tài)置為NONE_SNDST,然后構(gòu)建發(fā)送請求數(shù)據(jù)包,該數(shù)據(jù)包中包含數(shù)據(jù)請求標(biāo)志、數(shù)據(jù)編號和待發(fā)送數(shù)據(jù)長度;(其中,待發(fā)送數(shù)據(jù)長度是重要的數(shù)據(jù)項,可以保證服務(wù)端接收數(shù)據(jù)時對即將接收到的數(shù)據(jù)長度的控制。)然后將發(fā)送狀態(tài)置為WAITSNDACK_SNDST。

      服務(wù)端的接收線程通過使用select()函數(shù),對多個套接字描述符進(jìn)行一定時間的等待,判定描述符是否有新數(shù)據(jù)到來。當(dāng)有數(shù)據(jù)到來時,通過線程池啟動的線程接收數(shù)據(jù),對數(shù)據(jù)進(jìn)行處理。先將接收狀態(tài)置為NONE_RECVST,此時接收的數(shù)據(jù)是客戶端發(fā)送的數(shù)據(jù)請求。對該請求進(jìn)行處理,如果是數(shù)據(jù)發(fā)送請求,得到數(shù)據(jù)長度;如果是文件發(fā)送請求,得到文件名和文件長度。將發(fā)送狀態(tài)置為READY_RECVST,構(gòu)建發(fā)送請求響應(yīng)包,包中包括響應(yīng)標(biāo)志和發(fā)送請求中的數(shù)據(jù)編號并發(fā)送請求響應(yīng)。發(fā)送成功后,將接收狀態(tài)置為RECVING_RECVST。

      客戶端接收到請求響應(yīng)數(shù)據(jù)包,對響應(yīng)進(jìn)行驗證,驗證正確后,發(fā)送狀態(tài)轉(zhuǎn)為READY_SNDST。每次讀取一定數(shù)量字節(jié)的數(shù)據(jù),進(jìn)行循環(huán)發(fā)送,直到發(fā)送數(shù)據(jù)的字節(jié)數(shù)等于待發(fā)送數(shù)據(jù)的字節(jié)數(shù),表明此次數(shù)據(jù)完全發(fā)送結(jié)束,將發(fā)送狀態(tài)置為SNDED_SNDST。

      對等服務(wù)端循環(huán)接收客戶端發(fā)送的數(shù)據(jù)。如果是內(nèi)存數(shù)據(jù),接收直到已接收數(shù)據(jù)的字節(jié)數(shù)大于等于預(yù)期的接收字節(jié)數(shù),回調(diào)組件的接收數(shù)據(jù)接口函數(shù),將接收到的完整數(shù)據(jù)通過回調(diào)接收函數(shù)發(fā)送給應(yīng)用程序;如果是文件數(shù)據(jù),先在當(dāng)前目錄創(chuàng)建該文件,然后將接收到的文件數(shù)據(jù)內(nèi)容寫入文件,直到寫入的字節(jié)數(shù)等于預(yù)期接收的文件字節(jié)數(shù)。將接收狀態(tài)置為RECVED_RECVST,此次數(shù)據(jù)接收完成。

      對等傳輸組件的工作原理如圖1所示。

      圖1 傳輸組件的工作原理

      傳輸組件在客戶和服務(wù)之間交互過程的狀態(tài)控制,提高了組件傳輸?shù)目煽啃浴?/p>

      2 技術(shù)實現(xiàn)

      2.1 IO多路復(fù)用服務(wù)模型

      Socket的讀寫模型有3種:阻塞方式、非阻塞方式和 IO 多路復(fù)用[1-4]。

      阻塞方式:應(yīng)用進(jìn)程調(diào)用read()或recv()函數(shù)時,若套接字緩沖區(qū)沒有可讀或可寫的數(shù)據(jù)時,則函數(shù)將被阻塞,進(jìn)程進(jìn)入睡眠等待狀態(tài),直到有數(shù)據(jù)到來,進(jìn)程才被喚醒。阻塞式IO模型的結(jié)構(gòu)簡單,但是進(jìn)程的效率低,因為應(yīng)用進(jìn)程不能及時處理多個套接字的情況。

      非阻塞方式:當(dāng)進(jìn)程調(diào)用read()或recv()函數(shù)時,若套接字緩沖區(qū)沒有數(shù)據(jù)或有部分?jǐn)?shù)據(jù)都會立即返回。非阻塞方式相比較阻塞方式雖然進(jìn)程效率有些提高,但因為每個套接字都要讀取多次,所以在多個套接字的情況下,需要對每個套接字進(jìn)行輪詢而占用大量的CPU時間。

      IO多路復(fù)用:IO復(fù)用可以在進(jìn)程睡眠的狀態(tài)下實現(xiàn)對多個套接字的檢測,任何一個套接字上發(fā)生事件時,由linux系統(tǒng)去喚醒進(jìn)程,這樣就能節(jié)省大量的CPU時間。

      在該傳輸組件中,客戶端的發(fā)送線程和服務(wù)端的接收線程是通過使用socket的IO多路復(fù)用模型,來實現(xiàn)對數(shù)據(jù)的發(fā)送和接收的。其實現(xiàn)方式是通過select()函數(shù):函數(shù)定義形式為:

      Int select(int maxfd,fd_set*read_set,fd_set*write_set,fd_set except_set,const struct timeval*timeout);

      其中,maxfd是需要檢測的文件描述符最大值加 1,read_set、write_set和 except_set參數(shù)分別對應(yīng)于需要檢測的可讀描述符集,可寫描述符集和異常描述符集,timeout是select函數(shù)的最大等待時間。

      以發(fā)送端的發(fā)送線程為例:循環(huán)發(fā)送套接字列表,并依次調(diào)用FD_SET(*iterSock,&sockSet)函數(shù)將每個套接字描述符*iterSock在sockSet中的相應(yīng)位開放,并通過

      }來記錄maxsock的最大值。調(diào)用INT iRes=select(maxsock,NULL,&sockSet,NULL,&tval),如果iRes>0,則在 sockSet集合中有一個或多個 socket可寫數(shù)據(jù)。再次循環(huán)socket發(fā)送列表,并通過FD_ISSET((*iterSock),&sockSet))函數(shù)確定某個socket達(dá)到了寫條件,然后對該socket中的數(shù)據(jù)進(jìn)行發(fā)送操作。

      Socket的IO多路復(fù)用綜合了阻塞式與非阻塞式輸入輸出的優(yōu)點,提高了傳輸組件的進(jìn)程效率,增加了數(shù)據(jù)處理的時效性。

      2.2 實現(xiàn)并應(yīng)用線程池

      傳輸組件的客戶端會向多個不同地址的客戶端發(fā)送數(shù)據(jù),服務(wù)端也會接收多個不同地址客戶端發(fā)來的數(shù)據(jù)。在這種多用戶并發(fā)的情況下,為了能夠及時響應(yīng)并處理多個不同端地址的數(shù)據(jù),需要使用多個線程。傳統(tǒng)的多線程服務(wù)模型是當(dāng)新數(shù)據(jù)請求到來時,就創(chuàng)建新線程,線程執(zhí)行完任務(wù)后退出。盡管創(chuàng)建和銷毀線程是輕量級的,但過于頻繁的話,就會給服務(wù)造成很大的負(fù)擔(dān)[5-7]。為了解決上述問題,傳輸組件實現(xiàn)并使用了自適應(yīng)的線程池。

      線程池可以統(tǒng)一任務(wù)接口,通過線程復(fù)用將創(chuàng)建和銷毀線程的開銷分?jǐn)偟蕉鄠€任務(wù)上。線程池的實現(xiàn)包括4部分:線程池管理器、工作線程、任務(wù)接口和任務(wù)隊列。

      線程池管理器:用于創(chuàng)建和管理池中的工作線程,并將工作任務(wù)按需分配到不同的線程中;

      工作線程:執(zhí)行實際任務(wù)的線程;

      任務(wù)接口:執(zhí)行任務(wù)函數(shù)和參數(shù)的地址;

      隊列:保存待執(zhí)行任務(wù)的列表和工作線程的列表。

      以客戶端發(fā)送數(shù)據(jù)為例:當(dāng)向新的客戶端發(fā)送數(shù)據(jù)時,發(fā)送客戶端將發(fā)送任務(wù)添加到線程池管理器的任務(wù)隊列,線程池管理器找出空閑線程后,將該任務(wù)分配到線程中去執(zhí)行。需要注意的是,為了保證數(shù)據(jù)的按序發(fā)送,需要對添加的每個任務(wù)設(shè)置是否完成標(biāo)志,來保證每條數(shù)據(jù)按序正常的發(fā)送。以客戶端為例,傳輸組件通過線程池執(zhí)行任務(wù)的代碼如下:

      2.3 TCP粘包的處理

      TCP是面向連接的并且提供了一個可靠的字節(jié)流信道,數(shù)據(jù)流可以通過這個信道在兩個終端系統(tǒng)之間流動。由于TCP協(xié)議的傳輸特點,為了提高效率,TCP在發(fā)送方會將多個待發(fā)送的數(shù)據(jù)包一起發(fā)送。發(fā)送方發(fā)送的若干包數(shù)據(jù)到達(dá)接收方接收時粘成一包,即多個數(shù)據(jù)包首尾相連,稱為粘包[8,9]。

      通常解決粘包現(xiàn)象的方法是:接收方創(chuàng)建一個預(yù)處理線程,對接收到的數(shù)據(jù)包進(jìn)行預(yù)處理,將粘包分開。

      本傳輸組件因為是對等傳輸,所以可以通過在客戶端和服務(wù)端之間的傳輸過程中加入控制機(jī)制,來避免對粘包的單獨處理。采取的措施如下:

      ①在每一次數(shù)據(jù)傳輸之前,都會先進(jìn)行一個發(fā)送數(shù)據(jù)請求和返回請求響應(yīng)的交互過程。該交互過程主要是在發(fā)送方和接收方之間確定即將傳輸數(shù)據(jù)的大小,這樣接收方就可以在數(shù)據(jù)傳送之前確定本次應(yīng)該接收的數(shù)據(jù)的確切大小;

      ②第1次數(shù)據(jù)傳輸結(jié)束之后,會將發(fā)送狀態(tài)置為發(fā)送完畢,第2條數(shù)據(jù)就會開始發(fā)送數(shù)據(jù)請求。而由于TCP的傳輸機(jī)制,會將第1條的全部或部分?jǐn)?shù)據(jù)和第2條的數(shù)據(jù)請求包粘在一起進(jìn)行發(fā)送。因為發(fā)送方對于第2條數(shù)據(jù)沒有收到請求響應(yīng)之前,不會發(fā)送真正數(shù)據(jù)內(nèi)容,所以粘在后面的數(shù)據(jù)部分只可能是第2個數(shù)據(jù)包的數(shù)據(jù)請求。接收方先基于第1條數(shù)據(jù)請求中攜帶的數(shù)據(jù)長度,從粘包數(shù)據(jù)中截取真正的數(shù)據(jù)內(nèi)容,然后將剩下的數(shù)據(jù)作為第2包的數(shù)據(jù)請求報進(jìn)行驗證處理。

      這種處理TCP粘包的方式比連續(xù)接收數(shù)據(jù),并啟動線程進(jìn)行單獨處理粘包數(shù)據(jù)的方式效率更高。

      2.4 豐富的傳輸接口和回調(diào)接口

      傳輸組件為了使上層應(yīng)用能夠更靈活地進(jìn)行數(shù)據(jù)傳輸和得到更多的數(shù)據(jù)傳輸信息,組件提供了較為豐富的傳輸接口和回調(diào)接口[10-12]。

      傳輸接口:提供了對數(shù)據(jù)和文件的異步和同步發(fā)送。如異步發(fā)送數(shù)據(jù)接口:

      virtual LONG SendData(const BYTE* pBuf,const ULONG ulSndLen,const PeerAddress& peeraddr,const ULONG uiBlockNotifySize,UINT & uiSnd-Num)=0;

      其中,const BYTE*pBuf為指向待發(fā)送數(shù)據(jù)的指針;const ULONG ulSndLen為待發(fā)送數(shù)據(jù)長度;const PeerAddress&peeraddr為待發(fā)送數(shù)據(jù)的目的地址,其中PeerAddress為自定義的地址結(jié)構(gòu),包括端口號和IP地址等;const ULONG uiBlockNotifySize是設(shè)置已傳輸數(shù)據(jù)多大時通知給應(yīng)用;UINT&uiSnd-Num是數(shù)據(jù)編號,可以為空。組件還提供了傳輸文件的異步接口SendFile,可同時發(fā)送數(shù)據(jù)和文件的異步接口SendDataAndFiles。

      回調(diào)接口:組件通過回調(diào)接口可以接收文件或數(shù)據(jù),還可以接收在傳輸過程中接收數(shù)據(jù)或傳輸數(shù)據(jù)的大小等。如接收數(shù)據(jù)回調(diào)接口:

      virtual LONG OnRecvData(const BYTE*pData,const ULONG ulLen,const DataTime& tmDataRecv,const PeerAddress& peeraddr)=0;//接收數(shù)據(jù)

      其中,const BYTE*pData為傳入的接收到的數(shù)據(jù)指針,const ULONG ulLen是接收到的數(shù)據(jù)長度,const DataTime&tmDataRecv是數(shù)據(jù)接收的時間,const PeerAddress&peeraddr是數(shù)據(jù)的發(fā)送地址。

      組件還提供了接收文件的回調(diào)接口OnRecv-File,當(dāng)前接收數(shù)據(jù)大小的回調(diào)接口OnRecvingData-Size,當(dāng)前發(fā)送文件數(shù)據(jù)的大小 OnFileTransSize,發(fā)送結(jié)果OnSendResult。還有連接斷開OnDisconnect函數(shù),OnConnError連接錯誤等函數(shù)。通過這些回調(diào)函數(shù)接口,應(yīng)用進(jìn)程可以獲得更多的傳輸狀態(tài),發(fā)送結(jié)果等信息。

      3 組件測試

      傳輸組件的功能是為信息系統(tǒng)中的數(shù)據(jù)流轉(zhuǎn)軟件提供及時和可靠的數(shù)據(jù)傳輸,并且在多用戶并發(fā)的情況下也能夠滿足。針對這一特性,在測試階段為傳輸組件設(shè)計了多種性能測試。測試內(nèi)容主要是針對多用戶并發(fā)、大數(shù)據(jù)塊和大數(shù)據(jù)量等不同條件下,組件傳輸數(shù)據(jù)的時效性和可靠性。經(jīng)過大量的測試實驗后,表明該傳輸組件可以為數(shù)據(jù)流轉(zhuǎn)軟件提供及時和可靠的傳輸服務(wù)。

      4 結(jié)束語

      Linux下基于TCP的傳輸組件,可以為數(shù)據(jù)流轉(zhuǎn)軟件和其他上層應(yīng)用軟件提供底層的數(shù)據(jù)和文件傳輸,是信息系統(tǒng)中重要支撐功能;同時,數(shù)據(jù)傳輸?shù)姆€(wěn)定性、可靠性和及時性,更是上層應(yīng)用所關(guān)心的,所以性能成為了評價傳輸組件優(yōu)劣非常關(guān)鍵的因素。

      本文中所探討的組件實現(xiàn)通過在組件中應(yīng)用多種技術(shù),提高了組件的傳輸性能。首先在TCP傳輸協(xié)議上增加自控機(jī)制提高了數(shù)據(jù)傳輸?shù)姆€(wěn)定性和可靠性,也提高了粘包數(shù)據(jù)的處理效率;采用socket的多路復(fù)用與線程池技術(shù),提高了組件傳輸數(shù)據(jù)的及時性;豐富的傳輸接口和回調(diào)接口可以滿足不同上層應(yīng)用軟件的要求,也提供了更全面的傳輸信息。

      [1] 天夜創(chuàng)作室.Linux網(wǎng)絡(luò)編程技術(shù)[M].北京:人民郵電出版社,2001.

      [2] 宋敬彬,孫海濱.Linux網(wǎng)絡(luò)編程[M].北京:清華大學(xué)出版社,2010.

      [3] 張斌.Linux網(wǎng)絡(luò)編程[M].北京:清華大學(xué)出版社,2000.

      [4] 陳娟,趙振平.TCP/IP高效編程[M].北京:人民郵電出版社,2011.

      [5] 王雷,王子淘.基于Linux的Socket網(wǎng)絡(luò)編程的性能優(yōu)化[J].電子設(shè)計工程,2009,17(9):101 -103.

      [6] 唐富強(qiáng),于鴻洋,張萍.Linux下通用線程池的改進(jìn)與實現(xiàn)[J].計算機(jī)工程與應(yīng)用,2012 48(28):77-83.

      [7] 郭東升,田秀華.Linux環(huán)境下基于socket的網(wǎng)絡(luò)通信[J].軟件導(dǎo)刊,2009,8(1):116 -118.

      [8] 李慧霸,田甜,彭宇行,等.網(wǎng)絡(luò)程序設(shè)計中的并發(fā)復(fù)雜性[J].軟件學(xué)報,2011,22(1):132 -148.

      [9] 劉新強(qiáng),曾兵義.用線程池解決服務(wù)器并發(fā)請求的方案設(shè)計[J].現(xiàn)代電子技術(shù),2011,34(15):141 -143.

      [10]崔弘珂.一種空間環(huán)境下的TCP傳輸技術(shù)研究[J].無線電通信技術(shù),2011,37(4):21 -24.

      [11]宋廣怡.超寬帶高速數(shù)據(jù)傳輸技術(shù)研究[J].無線電工程,2014,44(5):23 -25

      [12]李志高,周音,孫學(xué)斌,等.認(rèn)知無線電網(wǎng)絡(luò)中一種改進(jìn)的傳輸層協(xié)議[J].無線電工程,2011,41(10):1 -3.

      猜你喜歡
      接收數(shù)據(jù)發(fā)送數(shù)據(jù)服務(wù)端
      移動自組網(wǎng)中MAC層協(xié)議研究
      沖激噪聲背景下基于幅度預(yù)處理的測向新方法*
      低復(fù)雜度多輸入多輸出雷達(dá)目標(biāo)角度估計方法
      基于馬爾科夫鏈的LoRaWAN網(wǎng)絡(luò)節(jié)點性能分析
      帶標(biāo)記方式的CRDSA++協(xié)議性能分析*
      云存儲中基于相似性的客戶-服務(wù)端雙端數(shù)據(jù)去重方法
      新時期《移動Web服務(wù)端開發(fā)》課程教學(xué)改革的研究
      在Windows Server 2008上創(chuàng)建應(yīng)用
      使用IPSec安全傳輸數(shù)據(jù)
      單片機(jī)模擬串口數(shù)據(jù)接收程序的實現(xiàn)及優(yōu)化
      香港 | 苍梧县| 马尔康县| 礼泉县| 兴城市| 兴业县| 桃园县| 山阳县| 荣昌县| 潍坊市| 保定市| 普兰县| 镇远县| 白银市| 枣阳市| 古交市| 昆山市| 土默特左旗| 白水县| 桓仁| 锡林郭勒盟| 大名县| 即墨市| 长沙市| 黔江区| 红河县| 石林| 大港区| 东阳市| 交口县| 大连市| 大田县| 永清县| 永寿县| 黑山县| 河间市| 合江县| 宽城| 龙口市| 镇坪县| 桦南县|