孫衛(wèi)佳, 許永康
(長(zhǎng)春工業(yè)大學(xué) 計(jì)算機(jī)科學(xué)與工程學(xué)院,吉林 長(zhǎng)春 130012)
隨著Internet的飛速發(fā)展,在網(wǎng)絡(luò)上看電影、電視劇,以及網(wǎng)絡(luò)視頻聊天等傳輸音視頻數(shù)據(jù)非常常見(jiàn),但是目前的網(wǎng)絡(luò)環(huán)境并不理想,使得用戶一旦處在網(wǎng)絡(luò)環(huán)境不太好的時(shí)間段或者空間段,音視頻應(yīng)用的性能急劇降低,讓用戶覺(jué)得“很卡”。
為此,文中嘗試開(kāi)發(fā)了一個(gè)音視頻聊天系統(tǒng),使用TCP/IP協(xié)議棧的分片技術(shù)把數(shù)據(jù)包進(jìn)行分片,并在接收端對(duì)其進(jìn)行重組。眾所周知,TCP/IP本身是有內(nèi)部分片的[1],但是其大小不能大于65 535字節(jié),并且只能按照默認(rèn)的1 514字節(jié)的大小在以太網(wǎng)中進(jìn)行傳輸,但是,網(wǎng)絡(luò)傳輸時(shí)延、路由器處理時(shí)延、丟包率等網(wǎng)絡(luò)參數(shù)均與數(shù)據(jù)包長(zhǎng)度相關(guān)[2],1 514字節(jié)的長(zhǎng)度在網(wǎng)絡(luò)環(huán)境良好時(shí),可以使音視頻應(yīng)用具有良好的效果,這一點(diǎn)在我們的音視頻聊天系統(tǒng)中可以看到,但是一旦網(wǎng)絡(luò)環(huán)境不好,可用帶寬減小的時(shí)候,只依靠IP本身的分片已經(jīng)難以滿足用戶的需求[3]。
文中的主要工作是先構(gòu)建一個(gè)音視頻聊天系統(tǒng),可以讓用戶在系統(tǒng)中進(jìn)行音視頻聊天,在這個(gè)過(guò)程中,自然會(huì)涉及到音視頻數(shù)據(jù)的大量傳輸。本系統(tǒng)視頻使用FFMPEG的類庫(kù)對(duì)視頻從攝像頭進(jìn)行采集,將其解碼為YUV420P的數(shù)據(jù),然后使用H.264編碼,將一幀一幀的視頻數(shù)據(jù)通過(guò)分片傳輸使用Winpcap類庫(kù)中的pcap_sendpacket()函數(shù)構(gòu)建一個(gè)發(fā)送隊(duì)列[4],將其發(fā)送到客戶端,因?yàn)閜cap_sendpacket()是發(fā)送的數(shù)據(jù)包隊(duì)列,該隊(duì)列保存在內(nèi)核級(jí)的緩沖區(qū),可以減少I/O上下文的交換,客戶端首先進(jìn)行重組,將之前自己分片的數(shù)據(jù)重組為完整的一幀H.264數(shù)據(jù),然后將其解碼,將H.264的數(shù)據(jù)變?yōu)閅UV數(shù)據(jù),然后再將YUV數(shù)據(jù)通過(guò)SDL類庫(kù)根據(jù)用戶的需要顯示到MFC中的Picture控件中,當(dāng)然也可以使用SDL本身的窗口進(jìn)行播放。
音頻方面使用Windows的API,Waveinopen()打開(kāi)音頻設(shè)備,采集到PCM格式的音頻數(shù)據(jù),設(shè)置好采樣率、信道、雙工/非雙工,再次使用FFEPEG中的函數(shù)編碼為AAC格式的數(shù)據(jù),同樣用上文所描述的方法傳輸?shù)娇蛻舳耍蛻舳诉M(jìn)行重組之后,通過(guò)回調(diào)函數(shù)將收到的重組完的AAC數(shù)據(jù)解碼為PCM數(shù)據(jù),同樣通過(guò)SDL播放出來(lái)。
核心技術(shù)為基于TCP/IP協(xié)議棧的分片以及重組。
TCP/IP協(xié)議棧本身有一個(gè)重要功能,對(duì)數(shù)據(jù)量過(guò)大的數(shù)據(jù)進(jìn)行分片,IP首部之內(nèi)有三個(gè)字段與分片相關(guān):標(biāo)識(shí)字段,MF位,片偏移。其中標(biāo)識(shí)字段是區(qū)分不同的數(shù)據(jù)包的,具體到系統(tǒng)中就是用來(lái)區(qū)分一幀與下一幀的視頻數(shù)據(jù),其中有P幀、B幀,在分片的時(shí)候是一視同仁的,只是大小不同而已。但是在編碼的時(shí)候這個(gè)比較重要。
MF位代表還再不再分片,我們分片的前幾片,MF位為0X01,表示還有分片,片偏移是一個(gè)能被8整除的數(shù),標(biāo)識(shí)距離第一片的偏移位,當(dāng)然最后一片的片偏移達(dá)到最大,MF位為0,表示不再分片。
數(shù)據(jù)包分片情況如圖1所示。
圖1 數(shù)據(jù)包分片情況
圖1 為在WIRESHARK中截取到的圖片,通過(guò)Winpcap編程將每一片的以太網(wǎng)首部(14字節(jié))、IP首部(一般為20字節(jié))、UDP首部以及UDP偽首部加入到數(shù)據(jù)前面,封裝為一個(gè)完整的數(shù)據(jù)包,其中以太網(wǎng)首部由Windows API中的函數(shù)SENDARP獲得,其中源MAC可以由Winpcap所提供的鏈表由本機(jī)IP所獲得,GetAdaptersInfo(pAdapterInfo,&ulOutBufLen)[5],由此函數(shù)可得所需要的IP以及MAC,因?yàn)橐粋€(gè)網(wǎng)卡都可能有不同的IP,假如使用Windows的API中的函數(shù)通過(guò)計(jì)算機(jī)名稱獲得IP的話,可能存在你所用的IP和鏈表獲得的IP不一致的情況,至于對(duì)方的IP地址,是根據(jù)用戶需要選擇的,Mac地址則可以通過(guò)SENDARP獲得,在以太網(wǎng)首部中,還需要填充IP協(xié)議類型,一般為IPV4。
在IP首部中,協(xié)議類型中可以指定為UDP,因?yàn)閁DP相對(duì)于TCP可以比較實(shí)時(shí)地傳輸音視頻數(shù)據(jù),TTL為數(shù)據(jù)包的生存時(shí)間,表示允許經(jīng)過(guò)的路由器跳數(shù),片偏移則由數(shù)據(jù)部分的大小和首部長(zhǎng)度共同決定,并且需要計(jì)算校驗(yàn)和[6]。如果校驗(yàn)不正確,是發(fā)送不成功的。在UDP首部中,可以指定IP地址、源端口和目的端口等信息,本系統(tǒng)暫時(shí)是提前定好的端口號(hào)。IP地址等信息同上方式[7]。
本系統(tǒng)中,由編碼好的H.264視頻數(shù)據(jù)以及AAC音頻數(shù)據(jù)傳到分片的方法int fragment(unsigned char*temp,int size22)中,數(shù)據(jù)包總大小MTU的限制的算法會(huì)在后文中介紹,由此大小可以計(jì)算出分片的個(gè)數(shù),并為每一片指定一個(gè)索引號(hào)INDEX,這里分兩種情況:
1)普通情況:數(shù)據(jù)部分總大小不能被MTU整除。
其中fragment為每一片的大小,到最后一片的時(shí)候該變量為總大小與分片大小的余數(shù),并且把FLAGM值設(shè)為TRUE。
2)整除情況:這種情況發(fā)生的比較少,但是由于數(shù)據(jù)量大,還是會(huì)經(jīng)常發(fā)生:
此時(shí),最后一片大小與前幾片一樣。然后加上IP首部、以太網(wǎng)首部、UDP首部,至于添加的方法上文已經(jīng)提到,不再贅述。下面將IP首部中的重要參數(shù)進(jìn)行實(shí)時(shí)變化,例如非最后一片的時(shí)候,MF位為1,并且指定本分片的實(shí)際大小。
將IP首部、以太網(wǎng)首部、UDP首部放到計(jì)算校驗(yàn)和的函數(shù)中,得出結(jié)果。這是其中的一片,然后用Winpcap的數(shù)據(jù)包發(fā)送函數(shù),pcap_sendpacket()或者pcap_sendqueue_queue將數(shù)據(jù)包發(fā)送出去,其中第一個(gè)函數(shù)為簡(jiǎn)單的發(fā)送單個(gè)數(shù)據(jù)包,比較簡(jiǎn)單,但是效率不如下面那個(gè)函數(shù),第二個(gè)發(fā)送數(shù)據(jù)包隊(duì)列的函數(shù),先構(gòu)建一個(gè)發(fā)送隊(duì)列,然后將其發(fā)送,其中隊(duì)列保存在內(nèi)核級(jí)緩沖區(qū),減少上下文交換,發(fā)送完畢后,將隊(duì)列所申請(qǐng)的資源清零[8]。
至此,我們完成了數(shù)據(jù)包的手動(dòng)分片,可以將音視頻數(shù)據(jù)任意分割大小,至于MTU,Maximum Transmission Unit(最大傳輸單元)這個(gè)數(shù)值的設(shè)定,多少合適,文中應(yīng)用了統(tǒng)計(jì)學(xué)中的線性回歸的方法,通過(guò)大量的測(cè)量,將不同長(zhǎng)度的數(shù)據(jù)包在不同的網(wǎng)絡(luò)環(huán)境下的延遲插入到SQLSERVER數(shù)據(jù)庫(kù)中。
數(shù)據(jù)包延遲關(guān)系如圖2所示。
圖2 數(shù)據(jù)包延遲關(guān)系
測(cè)量了將近10萬(wàn)條數(shù)據(jù),然后用線性回歸的方法回歸出一個(gè)函數(shù):MTU=timeout/0.003 5;并且根據(jù)此式可以實(shí)時(shí)地調(diào)整數(shù)據(jù)包的大小。通過(guò)VPS算法,每隔一段時(shí)間發(fā)送一個(gè)探測(cè)報(bào)文,測(cè)試延遲,然后通過(guò)SETTIMER函數(shù)調(diào)整數(shù)據(jù)包的大小,并且定義回調(diào)函數(shù)來(lái)計(jì)算MTU的值,數(shù)據(jù)線性回歸如圖3所示。
圖3 數(shù)據(jù)線性回歸
圖中:X軸為數(shù)據(jù)包大小,Y軸為延遲的大小。
文中手動(dòng)進(jìn)行了分片,自然就要進(jìn)行重組,因?yàn)镮P協(xié)議棧并不會(huì)幫你完成這件事,由于文中用Winpcap發(fā)送,也用Winpcap進(jìn)行接收,使用Winpcap過(guò)濾的時(shí)候需要先設(shè)定打開(kāi)數(shù)據(jù)包的網(wǎng)絡(luò)接口為混雜模式,表示接收一切流過(guò)網(wǎng)卡的數(shù)據(jù)包,還有捕獲數(shù)據(jù)包的字節(jié)數(shù),讀取超時(shí)時(shí)間,這里設(shè)定為-1表示不管有沒(méi)有數(shù)據(jù)包都立即返回,設(shè)置為0表示不接收到數(shù)據(jù)包則不會(huì)返回,當(dāng)然,為了符合用戶的不同網(wǎng)絡(luò)環(huán)境,也可以根據(jù)延遲設(shè)定此值。然后要進(jìn)行過(guò)濾條件的編譯,Winpcap中的過(guò)濾條件是已聲明的謂詞為詞法基礎(chǔ),他包含了一個(gè)過(guò)濾表達(dá)式,pcap_compile()把這個(gè)表達(dá)式編譯成過(guò)濾器,如果沒(méi)有給出表達(dá)式,那么網(wǎng)絡(luò)中所有數(shù)據(jù)包均會(huì)被過(guò)濾引擎所認(rèn)可,關(guān)于表達(dá)式原語(yǔ)以及編譯表達(dá)式的技巧,我們會(huì)在另一篇文章中加以說(shuō)明[9]。然后打開(kāi)網(wǎng)卡設(shè)備,進(jìn)行過(guò)濾,通過(guò)非回調(diào)的方式獲得網(wǎng)卡的句柄,并且由res=pcap_next_ex(fp1,&header,&pkt_data)這個(gè)函數(shù)進(jìn)行捕獲我們之前分片的數(shù)據(jù)包,獲得正確的數(shù)據(jù)之后,即可通過(guò)MEMCPY進(jìn)行重組[10]。
此系統(tǒng)有兩個(gè)版本:
1)沒(méi)有經(jīng)過(guò)手動(dòng)分片的,直接用數(shù)據(jù)包套接字進(jìn)行收發(fā),通過(guò)實(shí)驗(yàn)可知,在網(wǎng)絡(luò)較好時(shí),表現(xiàn)不錯(cuò)。但是網(wǎng)絡(luò)不是很好的時(shí)候,會(huì)有卡的情況,占用的網(wǎng)絡(luò)帶寬為1.5Mbps;
2)我們分片重組的版本,不管網(wǎng)絡(luò)如何都不會(huì)出現(xiàn)卡頓的情況,并且占用的網(wǎng)絡(luò)帶寬較小。
分片重組技術(shù)在網(wǎng)絡(luò)日益重要的今天具有很好的應(yīng)用前景,可以在一定程度上緩解網(wǎng)絡(luò)狀況,使用戶獲得更好的體驗(yàn)。
[1] Richard Stevens W.TCP/IP協(xié) 議 詳 解 卷 二[J].2014,110(1):121-161.
[2] 陳敏.網(wǎng)絡(luò)實(shí)時(shí)視頻傳輸研究[D].廣州:華南理工大學(xué),2004.
[3] Lowerkamp B,Tierney B,Cotterll L,et al.A hierarchy of network performance charcteristics for grid applications and services[J].Proposed Recommendation,2003,95(2):1110-1115.
[4] Wang Y.Error control and concealment for video communicaion:AReview[J].Proceding of the IEEE,2000,502(2):1100-1156.
[5] Monetesino F,Pouzols.Comparative analysis of active bandwidth estimation tools procof passive and active measurement workshop[M].New York:ACM,2004:175-184.
[6] 王小凡.復(fù)雜網(wǎng)絡(luò)及其應(yīng)用[J].科學(xué)技術(shù)哲學(xué),2004(8):58-70.
[7] Issberg D S.Rise of the stupid network[J].Computer Telephony,2009(2):60-65.
[8] Downey A B.General aspects of quality of service and network performance indigital networks[J].Including ISDNs,2007(1):22-25.
[9] Paxon V,Almes G,Mahdavi J,et al.Frmework for IP performance[J].METRICS Ietf.Rfc.,1998(1):2330-2340.
[10] ZHANG Y.Duffield N on the constrancy of internet path properties[C]//Proceedings of the 1st ACM SIGCOMM Workshop on INTERNET Measruement.2010(1):3045-3056.