• <tr id="yyy80"></tr>
  • <sup id="yyy80"></sup>
  • <tfoot id="yyy80"><noscript id="yyy80"></noscript></tfoot>
  • 99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

    一種基于Go 語言的SIP 協(xié)議棧設(shè)計與實現(xiàn)

    2023-08-22 01:23:20鄧楊凡
    通信電源技術(shù) 2023年13期
    關(guān)鍵詞:編解碼狀態(tài)機服務(wù)端

    鄧楊凡

    (中國電子科技集團公司第三十研究所,四川 成都 610041)

    0 引 言

    會話初始協(xié)議(Session Initialization Protocol,SIP)是由互聯(lián)網(wǎng)工程任務(wù)組(Internet Engineering Task Force,IETF)制定的多媒體通信協(xié)議,具有結(jié)構(gòu)靈活、易于實現(xiàn)、便于擴展等特點[1]。利用SIP 協(xié)議可以實現(xiàn)用戶定位,檢查終端用戶的位置,用于通信。此外,還可以檢查用戶參與會話的意愿程度,在呼叫方和被叫方同時建立會話參數(shù),實現(xiàn)會話管理,包括會話的傳輸和終止、修改會話參數(shù)以及請求服務(wù)。

    目前主流的開源SIP 協(xié)議棧均采用C 語言開發(fā),隨著版本不斷迭代,其功能越來越強大,同時也存在一定不便之處,如功能、結(jié)構(gòu)越來越復(fù)雜,初學(xué)者的學(xué)習(xí)成本增加。同時,由于C 語言在各平臺版本庫之間存在差別,針對每個平臺需要進(jìn)行獨立的交叉編譯。文章基于Go 語言設(shè)計并實現(xiàn)了一種可以快速部署實現(xiàn)的SIP協(xié)議棧,由于采用原生Go語言進(jìn)行開發(fā),不采用任何C 語言的庫,跨平臺部署時僅需修改幾行配置文件即可,無須安裝各種編譯器和庫文件。

    1 SIP 協(xié)議

    1.1 SIP 協(xié)議棧結(jié)構(gòu)

    SIP 是一種應(yīng)用層協(xié)議,它獨立于傳輸層和物理層,可以通過不同的傳輸協(xié)議進(jìn)行傳輸,如用戶數(shù)據(jù)報協(xié)議(User Datagram Protocol,UDP)、傳輸控制協(xié)議(Transmission Control Protocol,TCP)以及安全傳輸層(Transport Layer Security,TLS)協(xié)議。其中,UDP 是目前最常用的協(xié)議。

    SIP 協(xié)議采用松耦合的分層關(guān)系結(jié)構(gòu),如圖1所示。

    圖1 SIP 協(xié)議棧層級結(jié)構(gòu)

    SIP 協(xié)議棧最底層是語法編碼層,該層的編碼方式是增強型的巴克斯范式(Augmented Backus-Naur Form,ABNF)。第2 層是傳輸層,它定義了客戶端與服務(wù)端之間的請求與響應(yīng)。第3 層是事務(wù)層,主要完成會話事務(wù)的管理。事務(wù)層采用有限狀態(tài)機機制,包括客戶端事務(wù)和服務(wù)端事務(wù),一個事務(wù)由客戶端事務(wù)發(fā)送給服務(wù)端事務(wù)的請求和服務(wù)端事務(wù)發(fā)送對應(yīng)該請求的響應(yīng)組成。SIP 協(xié)議棧的最上層是事務(wù)用戶層,除了無狀態(tài)的代理,每個SIP 實體都是事務(wù)用戶。當(dāng)一個事務(wù)用戶希望發(fā)送請求時,就創(chuàng)建一個客服端事務(wù)實例用于發(fā)送此請求。

    1.2 SIP 消息

    SIP 消息是基于文本的消息,采用UTF-8 字符集。SIP 將消息分為請求和響應(yīng)2 種類型,請求消息和響應(yīng)消息都采用RFC2822 規(guī)定的通用消息格式,包括起始行、一個或多個消息頭、一個空行以及一個可選消息體。SIP 消息的起始行分為請求行(Request-Line)和狀態(tài)行(Status-Line)。其中,請求行是請求消息的起始行,狀態(tài)行是響應(yīng)消息的起始行。請求消息包含請求行、消息頭、空行以及消息體,響應(yīng)消息包括狀態(tài)行、消息頭、空行以及消息體。RFC3261 規(guī)定的6 種請求消息如表1 所示。

    表1 SIP 請求消息

    SIP 響應(yīng)消息的第一行由狀態(tài)碼構(gòu)成,表示服務(wù)端的響應(yīng)狀態(tài)。RFC3261 規(guī)定了nXX(n從1 到6)的狀態(tài)碼定義,XX 用于對響應(yīng)狀態(tài)的進(jìn)一步描述。相關(guān)的響應(yīng)狀態(tài)編碼及其含義如表2 所示。

    表2 SIP 響應(yīng)消息類型

    2 協(xié)議棧模塊設(shè)計與實現(xiàn)

    根據(jù)對SIP 層級結(jié)構(gòu)和消息結(jié)構(gòu)的分析,結(jié)合工程實際需求,按照邏輯功能將SIP 協(xié)議棧分為不同的模塊,如圖2 所示。

    圖2 SIP 協(xié)議棧模塊劃分

    2.1 傳輸模塊

    傳輸模塊邏輯上處于SIP 協(xié)議棧的最底層,主要實現(xiàn)信令傳輸和媒體傳輸。傳輸模塊能夠收發(fā)SIP信令和實時傳輸協(xié)議(Real Time Transport Protocol,RTP)流媒體數(shù)據(jù),保證SIP 消息的完整性和正確的消息順序,根據(jù)消息類型進(jìn)行分發(fā)及錯誤處理[2]。

    傳輸模塊將編解碼模塊組包后的有效請求載荷通過特定端口進(jìn)行發(fā)送,并接收相應(yīng)的響應(yīng)消息,提取有效載荷后交由編解碼模塊進(jìn)行解析。SIP 消息的傳輸流程如圖3 所示。

    圖3 消息傳輸流程

    SIP 可以采用UDP、TCP 以及TLS 等傳輸協(xié)議作為傳輸承載。文章設(shè)計的SIP 協(xié)議棧采用UDP 作為傳輸協(xié)議,Go 語言原生提供net 包實現(xiàn)UDP 通信。以主叫方為例,上層用戶接口調(diào)用模塊發(fā)起一次呼叫時,即客戶端向服務(wù)端發(fā)送“Invite”消息前,程序使用net 包下的Dial 函數(shù)發(fā)起與SIP 服務(wù)端的連接,收到連接響應(yīng)后,調(diào)用net 包中的“Listen Packet”創(chuàng)建一個UDP 服務(wù),并提取返回結(jié)果中的UDP 服務(wù)端口值,將其作為Invite 消息中“media.port”參數(shù)的值,然后通過建立的UDP 通道發(fā)送該消息。服務(wù)端用于RTP 傳輸?shù)腢DP 服務(wù)端口的創(chuàng)建與之類似。UDP 傳輸建立的相關(guān)流程如圖4 所示。

    圖4 UDP 傳輸?shù)湫土鞒?/p>

    圖4 中,①和②分別是SIP 協(xié)議棧作為客戶端與服務(wù)端進(jìn)行RTP 傳輸協(xié)商并分配端口等待被叫端接聽后進(jìn)行RTP 流媒體傳輸?shù)倪^程。

    2.2 編解碼模擬

    編解碼模塊提供針對SIP消息的解析與編碼能力。SIP 協(xié)議類似于超文本傳輸協(xié)議(Hypertext Transfer Protocol,HTTP)協(xié)議,都是按行解析。SIP 消息的第一行標(biāo)識該消息的類型、消息目的地及協(xié)議版本。從第二行開始,每一行的格式為“字段名:空格 字段值”(冒號后固定有一個或多個空格)[3]。

    根據(jù)以上分析,為了驗證平臺的實際情況,設(shè)計一套多級流水線的文本消息處理流程。第1 級以空行為分割符,將消息分割為消息頭(Message Header)和消息體(Message Body)。第2 級解析消息頭與消息體中的回車換行符,以此標(biāo)志作為分割符,將消息分割為多條字段。第3 級以“:”作為分割符,獲取字段名稱。第4 級以“:”“@”等標(biāo)志作為分割符,過濾出字段的參數(shù)值。4 級流水線結(jié)構(gòu)的解碼模型如圖5 所示。

    圖5 4 級流水線結(jié)構(gòu)的解碼模型

    針對SIP(包含SDP 和RTP)的編碼可以看作解析的逆向過程,編碼模塊根據(jù)接收消息的內(nèi)容,結(jié)合當(dāng)前網(wǎng)絡(luò)狀態(tài),按照SIP 消息的標(biāo)準(zhǔn)生成消息頭和消息體,組合成相應(yīng)的載荷。文章設(shè)計的協(xié)議棧支持INVITE、BYE、RING 以及ACK 等多種消息的生成和解析,其消息編解碼模塊根據(jù)消息頭判斷消息類型,同時采用多級流水的模式進(jìn)行解析。

    實現(xiàn)上述編解碼時,接收消息為16 進(jìn)制的數(shù)組,此時使用Go 語言原生包“bytes”中的“splite”函數(shù),利用“0x0d,0x0a”作為分割關(guān)鍵數(shù)組,將收到的消息進(jìn)行分割,分割后的消息為一段包含關(guān)鍵字的字符串。此外,分割后第一段為消息類型或“Status Line”的值。獲取到接收消息的類型后,調(diào)用相應(yīng)的函數(shù)對相關(guān)消息進(jìn)行解析,獲取消息中“Call-ID”“From”“To”等關(guān)鍵參數(shù)的值進(jìn)行處理存儲。

    消息編碼利用SIP 協(xié)議文本性質(zhì)的特點,采用關(guān)鍵字填充模式進(jìn)行消息組包,通過對關(guān)鍵字的填充來生成消息載荷。SIP 消息組包的典型編程實現(xiàn)如圖6所示。

    圖6 SIP 消息組包的編碼實現(xiàn)

    2.3 數(shù)據(jù)處理與數(shù)據(jù)存儲模塊

    數(shù)據(jù)處理模塊接收編解碼模塊解析的數(shù)據(jù)并對其進(jìn)行處理,以供編解碼模塊生成響應(yīng)消息時使用。數(shù)據(jù)處理器根據(jù)編解碼模塊解析出的消息類型,調(diào)用對應(yīng)的處理函數(shù)對對方支持的媒體格式和本協(xié)議棧支持的媒體格式進(jìn)行對比處理,選擇其中的交集作為對端通信的媒體格式。

    SIP 消息通過文本形式進(jìn)行信息交互,收發(fā)雙方每次交付都會產(chǎn)生大量參數(shù),其中大部分參數(shù)在整個會話過程中都要使用。在支持多線程的情況下,相關(guān)參數(shù)的存儲量大幅增加,這就要求協(xié)議棧能夠?qū)崟r創(chuàng)建一個存儲空間來存儲上述數(shù)據(jù),同時相關(guān)函數(shù)可以方便地對其訪問[4]。

    結(jié)合Go 語言的特點,會話中的數(shù)據(jù)采用結(jié)構(gòu)體的形式進(jìn)行存儲。通過HashMap 的形式,采用一次會話中的唯一值“Call-ID”作為鍵值進(jìn)行檢索。會話開始時創(chuàng)建一條索引關(guān)系,會話結(jié)束或者會話中止時則刪除。中間可采用指針形式對索引中的值進(jìn)行修改。數(shù)據(jù)存儲模塊除了存儲一次會話中的SIP 參數(shù)信息,還存儲一次SIP 會話中的會話狀態(tài)信息。狀態(tài)信息采用SIP 消息中的“Status Code”作為主要參數(shù),同時加入部分自定義狀態(tài)。例如,協(xié)議棧作為客服端發(fā)送INVITE 消息后,則將狀態(tài)設(shè)置為“Wait-100”,同時設(shè)置一個計時器,開始等待“100 Trying”(INVITE消息的響應(yīng)消息)。

    數(shù)據(jù)處理存儲采用HashMap 的形式實現(xiàn),Go 語言提供了“sync.map”庫用作并發(fā)環(huán)境下實現(xiàn)效率高且線程安全的map。map 采用“Call ID”作為鍵值,索引內(nèi)容以結(jié)構(gòu)體的形式存在。存儲呼叫信息的結(jié)構(gòu)體如圖7 所示。

    圖7 存儲呼叫信息的結(jié)構(gòu)體

    存儲數(shù)據(jù)的結(jié)構(gòu)體采用值類型的形式進(jìn)行更新,每收到一條消息,就執(zhí)行一次判斷。如果當(dāng)前消息不是“BYE”,就提取“Call-ID”值,并同步更新上述的“sync.map”列表;如果收到的消息為“BYE”消息,就形成相應(yīng)的log,并刪除當(dāng)前消息“Call-ID”對應(yīng)的結(jié)構(gòu)體。

    2.4 有限狀態(tài)機

    有限狀態(tài)機是整個協(xié)議棧的控制核心,該模塊提供對協(xié)議棧運行的總體調(diào)度能力[5]。該模塊通過存儲模塊中存儲的“Status”作為狀態(tài)轉(zhuǎn)換的狀態(tài)值,通過一次會話中的唯一鍵值“Call ID”作為索引,獲取每次消息的“Status Code”或關(guān)鍵字(如BYE、ACK 等)作為狀態(tài)變換的更新。典型的有限狀態(tài)機結(jié)構(gòu)如圖8 所示。

    圖8 有限狀態(tài)機結(jié)構(gòu)

    有限狀態(tài)機的初始狀態(tài)為WAITING,若無主叫請求或收到被叫請求,則保持此狀態(tài)。此時根據(jù)主動發(fā)出會話請求和收到會話請求,狀態(tài)機會有2 種狀態(tài)走向。

    若由SIP 協(xié)議棧發(fā)起會話,則狀態(tài)機由WAITING轉(zhuǎn)為INVITE,并開啟一個定時器。若在一定時間內(nèi)沒有收到響應(yīng)消息,則重新跳轉(zhuǎn)至WAITING 狀態(tài),并拋出一個異常記錄;若在一定時間內(nèi)收到“100 Trying”回復(fù),則進(jìn)入下一個狀態(tài),等待被叫方回復(fù)“180 Ring”響應(yīng)消息;若收到“180 Ring”消息后,狀態(tài)機轉(zhuǎn)為RINGING 狀態(tài)并等待200 OK 消息,狀態(tài)機轉(zhuǎn)為ACK 狀態(tài)并向?qū)Χ税l(fā)送“ACK”響應(yīng),同時打開會話并啟動RTP 多媒體傳輸;若收不到相應(yīng)的響應(yīng),則重新轉(zhuǎn)到WAITING 狀態(tài),重新等待會話開始。

    若協(xié)議棧收到會話請求時,狀態(tài)機由WAITING轉(zhuǎn)為RINGING。此時協(xié)議棧開啟定時機制,等待用戶接收或中止該請求。若目標(biāo)用戶接受請求,則將狀態(tài)機置為OK 狀態(tài),回復(fù)“200 OK”響應(yīng),等待對方最終請求為ACK 后,狀態(tài)機由OK 狀態(tài)轉(zhuǎn)換為ACK,開啟會話和RTP 媒體傳輸;若用戶放棄該請求,則將狀態(tài)重置為WAITING 狀態(tài),等待新的呼叫。

    終止會話時,請求方或響應(yīng)方發(fā)送BYE 請求,等待200 OK 消息,此時將狀態(tài)機由ACK 置為BYE狀態(tài)。當(dāng)一方接受BYE 請求后,狀態(tài)機重新復(fù)位到WAITING 狀態(tài),同時發(fā)送200 OK 響應(yīng)并釋放會話,此時一個會話結(jié)束。

    3 實驗驗證

    采用端到端的形式模擬一次SIP 呼叫與語音通話過程,利用虛擬機搭建服務(wù)端與客戶端。服務(wù)端系統(tǒng)采用Linphone,客戶端采用文章設(shè)計的協(xié)議棧系統(tǒng),讀取已經(jīng)生成的WAV 文件作為傳輸話音。實驗簡易部署結(jié)構(gòu)如圖9 所示。

    圖9 實驗簡易部署結(jié)構(gòu)

    圖9 中,主叫端為基于SIP 協(xié)議棧開發(fā)的SIP 客戶端軟件,其IP 地址為“192.168.46.147”,分配的主叫號碼為“22222222222”;被叫端采用Linphone軟件,其IP 地址為“192.168.46.142”,分配的被叫號碼為“11111111111”。實驗中SIP 信令抓包結(jié)果如圖10 所示。

    圖10 實驗中SIP 信令抓包結(jié)果

    由圖10 可知,基于SIP 協(xié)議棧開發(fā)的SIP 客戶端成功發(fā)起并處理了一次呼叫的全部信令流程。本次呼叫中傳輸?shù)腞TP 數(shù)據(jù)流如圖11 所示。

    圖11 實驗中傳輸?shù)腞TP 數(shù)據(jù)流

    4 結(jié) 論

    文章基于Go 語言設(shè)計并實現(xiàn)了一種輕型的SIP協(xié)議棧,在跨平臺部署時無須安裝各種編譯器和庫文件,應(yīng)用簡單便捷。通過在目標(biāo)主機上進(jìn)行實驗驗證,該協(xié)議棧具備主動發(fā)起呼叫并處理相關(guān)RTP 媒體流的能力,具有較好的應(yīng)用價值。

    猜你喜歡
    編解碼狀態(tài)機服務(wù)端
    1553B總線控制器編解碼設(shè)計
    基于有限狀態(tài)機的交會對接飛行任務(wù)規(guī)劃方法
    大型民機試飛遙測視頻編解碼方法研究
    基于H.265編解碼的高清視頻傳輸系統(tǒng)研究
    電子測試(2018年18期)2018-11-14 02:30:54
    云存儲中基于相似性的客戶-服務(wù)端雙端數(shù)據(jù)去重方法
    新時期《移動Web服務(wù)端開發(fā)》課程教學(xué)改革的研究
    在Windows Server 2008上創(chuàng)建應(yīng)用
    主流視頻編解碼軟件的硬件性能分析與設(shè)計
    計算機工程(2014年6期)2014-02-28 01:27:54
    “鴿子”玩升級 黑你沒商量
    FPGA設(shè)計中狀態(tài)機安全性研究
    景东| 彭阳县| 平利县| 武清区| 时尚| 绩溪县| 双鸭山市| 阳泉市| 绍兴县| 遵义市| 新源县| 建湖县| 鹰潭市| 龙岩市| 濮阳县| 正定县| 朝阳区| 辛集市| 姚安县| 军事| 麦盖提县| 大埔区| 酒泉市| 墨竹工卡县| 于都县| 丰顺县| 温州市| 大城县| 巴中市| 浦城县| 江口县| 漳平市| 永登县| 雷波县| 湘乡市| 托克托县| 施甸县| 巢湖市| 德阳市| 手游| 乌兰察布市|