首頁(yè)>>>技術(shù)>>>VoIP

解析:基于PC平臺的VoIP通信模式的實(shí)現

2007/02/05

1 序言

  近幾年來(lái)傳統電信業(yè)的發(fā)展勢頭逐漸減弱。在激烈的市場(chǎng)競爭中,電信業(yè)需要不斷地去尋找新的收入增長(cháng)點(diǎn)。VoIP在全球隨著(zhù)技術(shù)的成熟及各種人為管制的放松,開(kāi)始進(jìn)入一個(gè)新的發(fā)展時(shí)期。低廉的費用、低的帶寬、話(huà)音和數據應用的集成以及應用性廣泛等優(yōu)點(diǎn)使VoIP必然成為了人們的選擇。

  IP(Internet Protocol)電話(huà)是一種數字電話(huà),是技術(shù)創(chuàng )新的一種通信服務(wù)業(yè)務(wù)。它把語(yǔ)音、壓縮編碼、打包分組、分配路由、存儲交換、解包解壓等交換處理在IP網(wǎng)或互聯(lián)網(wǎng)上實(shí)現語(yǔ)音通信。

  傳統的電話(huà)網(wǎng)是以電路交換方式傳輸語(yǔ)音,所要求的傳輸寬帶為64kbit/s。而VoIP是以IP分組交換網(wǎng)絡(luò )為傳輸平臺,對模擬的語(yǔ)音信號進(jìn)行壓縮、打包等一系列的特殊處理,使之可以采用無(wú)連接的UDP協(xié)議進(jìn)行傳輸。不同編碼方案應用于VoIP,使得話(huà)音可以以不同的速率進(jìn)行傳輸,使得VoIP的傳輸帶寬進(jìn)一步減小到5-11kbit/s。

  傳統的電話(huà)網(wǎng)絡(luò )都有自己遵循的協(xié)議,在呼叫過(guò)程中都要用到這些協(xié)議,比如用于電路交換的7號信令等。H.323和sip信令協(xié)議被廣泛應用于VoIP網(wǎng)絡(luò )中。H.323是一個(gè)框架性協(xié)議,這一框架體系結構包括H.323終端、網(wǎng)關(guān)、關(guān)守和MCU。網(wǎng)關(guān)是VoIP的重要組成部分,網(wǎng)關(guān)完成了兩項功能的轉換,媒體信息編碼的轉換和信令的轉換。通過(guò)這兩種轉換,網(wǎng)關(guān)將TCP/IP網(wǎng)和PSTN網(wǎng)連接連了起來(lái)。

2 VoIP軟件的實(shí)現

  一般IP電話(huà)的業(yè)務(wù)可分為3類(lèi): PC-to-PC, PC-to-Phone和Phone-to-Phone。這里主要是針對PC-to-PC的編程過(guò)程進(jìn)行介紹。

  IP電話(huà)的基本數據流程為:呼叫方經(jīng)錄音設備獲取音頻流,然后對音頻流進(jìn)行編碼、壓縮、打包處理。其中計算機對輸入的不同類(lèi)型的數據進(jìn)行不同的處理(如果是音頻數據,采用無(wú)連接的UDP協(xié)議進(jìn)行傳輸;如果是信令和數據則采用面向連接的TCP協(xié)議進(jìn)行傳輸),然后經(jīng)網(wǎng)絡(luò )傳輸到被叫方。被呼叫方接收到數據以后,再進(jìn)行一系列的反變換,解包、解壓和解碼,送入放音緩沖區,經(jīng)音頻設備輸出語(yǔ)音。

  2.1 通信模塊的實(shí)現

  MFC中提供了封裝的Socket類(lèi),它提供了全面的由事件驅動(dòng)的Socket通信能力。程序必須按要求通過(guò)此Socket發(fā)送和接收數據。Winsock使用的是TCP協(xié)議或UDP協(xié)議,允許建立并保持一個(gè)到遠程計算機上的連接,且可以在連接結束之前實(shí)時(shí)地進(jìn)行數據交換。用戶(hù)僅通過(guò)設置屬性并借助事件處理就能輕而易舉地連接到一個(gè)遠程的計算機上。使用Winsock時(shí),通信的雙方需要選定相同的協(xié)議。TCP協(xié)議適用于傳送大容量、需要安全性保證的數據文件; 而UDP協(xié)議適用需要分別與很多下屬通信,或建立的連接比較多且為時(shí)變的情況,如語(yǔ)音通信。

  Socket是面向客戶(hù)/服務(wù)器模式設計的,它針對客戶(hù)和服務(wù)器程序提供了不同的系統調用。同時(shí)它還分為面向連接和無(wú)連接兩種類(lèi)型。對于語(yǔ)音傳輸,由于語(yǔ)音對實(shí)時(shí)性要求高,所以采用無(wú)連接的形式。而對于信令和數據傳輸,對準確性要求比較高,通常采用面向連接的形式。

  //服務(wù)器端
  sock=socket(AF_INET,SOCK_STREAM,0); //創(chuàng )建socket
  if (bind(sock,(sockaddr*)&serv,addlen)) //綁定
  {
  m_edit.SetWindowText("bind error");
  }
  listen(sock,5);
  AfxBeginThread(serthread,0); //調用線(xiàn)程
  //客戶(hù)端
  clisock=socket(AF_INET,SOCK_STREAM,0);// 創(chuàng )建socket
  while(connect(clisock,(sockaddr*)&(cli),sizeof(cli))!=0)
  {
  dlg->m_edit.SetWindowText("等待.....");
  for (int i=0;i<=65000;i++) //空循環(huán)
  for(int j=0;j<=200;j++);
  ………
  }

  2.2 音頻模塊的實(shí)現

  IP電話(huà)音頻功能的實(shí)現主要包括語(yǔ)音的錄制和播放。因為在IP電話(huà)中采集實(shí)時(shí)的音頻數據而不是WAVE文件,而且要把實(shí)時(shí)的語(yǔ)音數據傳輸出去,所以編程過(guò)程中采用了底層音頻處理函數, 這些函數允許應用程序直接與底層驅動(dòng)程序通信,對錄制和播放提供更靈活的控制。對于波形設備來(lái)說(shuō),不論是錄制還是播放波形,系統要處理的數據量都很大,為了少占用內存,底層服務(wù)函數以數據塊為單位進(jìn)行處理, 應用程序要自己分配內存,并將內存塊的地址、大小等信息告訴底層音頻驅動(dòng)程序。

  首先介紹幾個(gè)要用到的數據結構。WAVEFORMATEX結構定義了WAVE音頻數據文件的格式。WAVEHDR結構定義了波形音頻緩沖區。讀出的數據首先要填充此緩沖區才能送音頻設備播放,聲音的采集和播放都是在操作這個(gè)音頻數據塊結構。 實(shí)際上主要用到的就是第一個(gè)成員變量lpData,所以只要在分配緩沖區(內存)的同時(shí)相應分配WAVEHDR數據塊結構, 然后將緩沖區的指針賦給對應的數據塊結構的成員變量lpData,這樣當一個(gè)緩沖區填滿(mǎn)后,也就是一個(gè)音頻數據塊填滿(mǎn)了,通過(guò)消息機制就可以在消息函數中進(jìn)行處理和播放,播放完后又可通過(guò)消息函數把緩沖區再送給音頻設備輸入驅動(dòng)程序,繼續進(jìn)行采集并播放。

  當一次性分配多個(gè)緩沖區和數據塊結構并賦給音頻設備輸入驅動(dòng)程序后,至于把哪個(gè)緩沖區填滿(mǎn),然后再把哪個(gè)空緩沖區賦給設備輸入驅動(dòng)程序,不需人為干預,完全由Windows控制。在程序設計中可以使用兩個(gè)數據塊,交替進(jìn)行,當正播放第一個(gè)緩沖區,就用第二個(gè)緩沖區接收。

  //檢查語(yǔ)音輸入/輸出設備
  if(!waveInGetNumDevs())
  {
  return FALSE;
  }
  if(!waveOutGetNumDevs())
  {
  return FALSE;
  }
  //打開(kāi)音頻設備之前,需要先設置音頻數據格式
  ……………
  //分配緩沖區所需要的內存
  pWaveOutHdr=(LPWAVEHDR)GlobalAllocPtr(GHND|GMEM_SHARE,sizeof(WAVEHDR));
  pWaveHdr1=(LPWAVEHDR)GlobalAllocPtr(GHND|GMEM_SHARE,sizeof(WAVEHDR));
  pWaveHdr2=(LPWAVEHDR)GlobalAllocPtr(GHND|GMEM_SHARE,sizeof(WAVEHDR));
  //放音緩沖區
  pOutBuffer1=(char*)GlobalAllocPtr(GHND|GMEM_SHARE,PCMBUFFER_SIZE*BLOCK_PER_BUFFER+500);
  pOutBuffer2=(char*)GlobalAllocPtr(GHND|GMEM_SHARE,PCMBUFFER_SIZE*BLOCK_PER_BUFFER+500);
  rBuffer=(char*)GlobalAllocPtr(GHND|GMEM_SHARE,PCMBUFFER_SIZE); //接收緩沖區
  //打開(kāi)音頻設備
  result=waveOutOpen((LPHWAVEOUT)&hWaveOut,WAVE_MAPPER,(LPWAVEFORMATEX)&pcm.wf,(DWORD)hwnd,0L,  CALLBACK_WINDOW)

  2.3 語(yǔ)音壓縮模塊的實(shí)現

  VoIP帶寬比電路交換更窄的主要原因是對數據進(jìn)行了壓縮處理。VoIP除了可使用最普通的編碼技術(shù)G.711外,還可以采用G.728, G.729, G.723.1等其它多種編碼方案。

  G.711有A律和μ律兩種形式。G.711通常被稱(chēng)為PCM(脈沖編碼調制)。如果在編程中選擇PCM編碼方式。

  G.711提供了良好的語(yǔ)音質(zhì)量,但是它的主要缺點(diǎn)是需要64Kbit/s的帶寬。所以在程序中靈活的選擇編碼方式是很重要的。

  ITU-T推薦的G.723.1標準可以同時(shí)支持兩種速率的編碼。一種是6.3kbit/s另一種是5.3kbit/s。所以,G.723.1在高速率下提供了好的通話(huà)質(zhì)量,是一種好的編碼方案。在程序中的實(shí)現是通過(guò)對G.723.1軟件包中相應功能函數的調用來(lái)完成的,而且,在進(jìn)行壓縮以前要將G.723.1的鏈接庫導入程序中。

  在需要進(jìn)行壓縮時(shí),要調用下面G.723.1的編碼和解碼函數:

  void Coder(FLOAT *DataBuff, char *Vout); //編碼
  void Decod(FLOAT *DataBuff, char *Vinp, short int Crc); //解碼

  2.4 RTP封裝

  因為語(yǔ)音傳輸對實(shí)時(shí)性要求非常高, 所以在程序中要采用基于UDP的RTP傳輸。UDP無(wú)法做到避免分組丟失和確保分組有序傳輸,運行在UDP上的RTP幫助實(shí)現了這些功能,RTP含有一個(gè)時(shí)間戳,可以利用這個(gè)時(shí)間戳來(lái)確保信息同步的傳輸給了目的用戶(hù)并計算出了時(shí)延和抖動(dòng)。

  在程序中要對語(yǔ)音數據進(jìn)行RTP格式封裝,使用了makertp()函數。而在解析是使用了isrtp()函數。

  LONG makertp(databuf *pdata,unsigned long ssrc_i,unsigned long timestamp_i,unsigned short seq_i,int spurt);
  BOOL isrtp(unsigned char *pkt,int len);

  在進(jìn)行RTCP 格式的封裝時(shí),使用了三個(gè)函數:

  rtcp_make_sdes();
  rtcp_make_sr();
  rtcp_make_rr()。

3 結論

  本文主要是利用VC++語(yǔ)言來(lái)實(shí)現PC-to-PC的軟件電話(huà),它提供給Internet用戶(hù)在全球任何地方上網(wǎng)便可以呼叫對方的能力,提高了通信效率,是一種新的通信模式。

中國聯(lián)通網(wǎng)站



相關(guān)鏈接:
從VoIP起步——網(wǎng)絡(luò )設備廠(chǎng)商眼中的融合通信 2007-02-02
多個(gè)VOIP電話(huà)PA168芯片組會(huì )話(huà)劫持漏洞 2007-02-02
VoIP發(fā)展的新方向-IP PBX 2007-02-02
2006至2007年度VOIP行業(yè)發(fā)展分析 2007-02-01
解析:邊緣接入控制解決VoIP問(wèn)題 2007-01-31

分類(lèi)信息:        
亚洲精品网站在线观看不卡无广告,国产a不卡片精品免费观看,欧美亚洲一区二区三区在线,国产一区二区三区日韩 溧水县| 绥棱县| 时尚| 陆丰市| 房产| 和硕县| 云龙县| 焉耆| 景宁| 盖州市| 永靖县| 南阳市| 怀安县| 龙川县| 江川县| 登封市| 新乡市| 蕲春县| 墨竹工卡县| 当涂县| 乐平市| 定陶县| 连江县| 聊城市| 沂水县| 梨树县| 五原县| 顺平县| 洱源县| 阜阳市| 靖远县| 邯郸县| 辉县市| 武安市| 宜丰县| 巴南区| 桑日县| 沙河市| 盐城市| 韩城市| 澄江县| http://444 http://444 http://444 http://444 http://444 http://444