<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Socket 面對的挑戰(zhàn)?

          共 4893字,需瀏覽 10分鐘

           ·

          2021-10-11 17:24


          在軟件中最普遍和生命力最強的接口之一就是是Socket API。Socket API最早是由由加州大學伯克利分校計算機系統(tǒng)研究小組開發(fā)的,在1982年作為 BSD 4.1c操作系統(tǒng)的一部分首次發(fā)布。雖然有一些使用時間更長的 API ,例如那些處理 Unix 文件 I/O 的 API ,但是一個 API 能夠保持使用并且近40年來基本上沒有變化,這是及其令人印象深刻的事情了。對Socket API 的主要更新是擴展了輔助程序,以適應 IPv6的大地址空間。

          互聯(lián)網和整個網絡世界自 socket API 誕生以來已經發(fā)生了非常重大的變化, API 已經改變了開發(fā)者思考和編寫網絡應用程序的方式,但是,網絡世界和各種服務的不斷變化,給socket API 帶來了哪些挑戰(zhàn)呢?

          Socket 的歷史

          1982年到如今,關于網絡的兩個最大區(qū)別是拓撲和速度。人們注意到的是速度的提高,而不是拓撲結構的變化。在1982年,商用長途網絡鏈路的最大帶寬是1.5 Mbps。而所部署的以太局域網速度為10mbps。局域網上兩臺計算機之間的往返時間以幾十毫秒計算,互聯(lián)網上各系統(tǒng)之間的往返時間以幾百毫秒計算,這當然取決于位置和一個數(shù)據(jù)包在計算機之間傳送時的跳數(shù)。一個家庭用戶能夠通過電話線連接到任何計算設備都是幸福的事,1995年,自己在當時的電報局申請了BTA的郵箱,并興奮了很久。

          當時的網絡拓撲結構相對簡單,大多數(shù)計算機只連接到一個局域網; 局域網連接到一個原始路由器,這個路由器可能有一些到其他局域網的連接或者到互聯(lián)網的一個連接。對于一個應用程序到另一個應用程序,連接要么跨越局域網,要么傳輸一個或多個路由器。

          分布式編程的模型中最普及的是基于socket API 的客戶端/服務器模型,其中有一個服務器和一組客戶端??蛻?/span>端向服務器發(fā)送消息,要求服務器代表它們完成工作,等待服務器完成請求的工作,然后在稍后的某個時刻收到答復。這種計算模型已經無處不在,它通常是許多軟件工程師所熟悉的唯一模型。然而,在設計socket的時候,它被看作是在計算機網絡上擴展 Unix 文件 I/O 模型的一種方法。另一個原因是它支持最流行的 TCP協(xié)議,本質上具有點對點的通信模型。

          Socket API 使客戶機/服務器模型易于實現(xiàn),程序員只需要將少量的系統(tǒng)調用添加到非聯(lián)網代碼中,就可以利用其他計算資源,這使得Socket API的客戶機/服務器模式已經成為主導網絡計算的模式。

          Socket 中的以下五個函數(shù)是 API 的核心,并且是與常規(guī)文件 I/O 的區(qū)別所在:

          socket()創(chuàng)建通信端點
          bind()將端點綁定到一組網絡層參數(shù)
          connect()連接服務器提交請求
          listen()?監(jiān)聽鏈路并設置請求的數(shù)量限制
          accept()接受來自客戶端的一個或多個請求


          實際上,socket ()調用可以替換為 open ()的一個變體,但是當時還沒有這樣做。Socket ()和 open ()實際上都是將相同的東西返回給程序: 一個進程唯一的文件描述符,并用于用于該 API 的所有后續(xù)操作。socket API 的簡單性導致了它的無處不在,但無處不在阻礙了替代或增強API 的開發(fā),而那些 API 可以幫助程序員開發(fā)其他類型的分布式應用程序。


          socket 面臨的挑戰(zhàn)

          客戶機/服務器的計算模式在開發(fā)時具有許多優(yōu)點。它允許許多用戶共享資源,有了這種共享模式,就有可能提高資源的利用率。

          然而,Socket AP在以下三個不同的網絡區(qū)域表現(xiàn)不佳:?

          • 低延遲或實時應用程序

          • 高帶寬應用程序

          • 多宿主系統(tǒng)(即具有多個網絡接口的系統(tǒng))。

          許多人混淆了增加網絡帶寬和提高性能,因為增加帶寬并不一定會減少延遲。Socket API 面臨的主要是性能挑戰(zhàn),即如何讓應用程序更快地訪問網絡數(shù)據(jù)。

          任何使用socket API 的程序發(fā)送和接收數(shù)據(jù)的方式都是通過對操作系統(tǒng)的調用。所有這些調用都有一個共同點: 調用程序必須不斷地請求要傳遞的數(shù)據(jù),因為服務器不能在沒有客戶機請求的情況下做任何事情。然而,如果服務是音樂或視頻呢,那該怎么辦?在媒體分發(fā)服務中,可能有一個或多個數(shù)據(jù)源和多個監(jiān)聽器。只要用戶在收聽或查看媒體,最有可能的情況是應用程序需要任何已經到達的數(shù)據(jù)。不斷地請求新數(shù)據(jù)是對應用程序的時間和資源的浪費。Socket API 沒有向程序員提供這樣一種方式: “無論何時有數(shù)據(jù)需要處理,都直接調用socket來處理它?!?/p>

          Socket 程序是從數(shù)據(jù)缺乏而不是數(shù)據(jù)豐富的角度編寫的。網絡程序非常習慣于等待數(shù)據(jù),因此使用一個單獨的系統(tǒng)調用例如 select () ,這樣就可以偵聽多個數(shù)據(jù)源,而不會阻塞單個請求?;?socket 的程序的典型處理循環(huán)不是簡單地 read ()、 process ()、 read () ,而是 select ()、 read ()、 process ()、 select ()。雖然將單個系統(tǒng)調用添加到循環(huán)中似乎不會增加太多負擔,但情況并非如此。每個系統(tǒng)調用都需要將參數(shù)封送并復制到內核中,同時導致系統(tǒng)阻塞調用進程并調度另一個進程。如果調用者在調用 select ()時可以獲得數(shù)據(jù),那么跨越用戶/內核邊界的所有工作都將被浪費,因為 read ()會立即返回數(shù)據(jù)。除非連續(xù)請求之間的間隔時間相當長,否則常規(guī)的檢查/讀取/檢查是一種浪費。

          要克服這個問題,需要反轉應用程序和操作系統(tǒng)之間的通信模型,提供一個允許內核直接調用程序的 API 。但各種嘗試中沒有一個獲得廣泛接受。在開發(fā)sockket API 時存在的操作系統(tǒng),在一般情況下,都是在單處理器計算機上執(zhí)行單線程的。如果內核反調 API,就會有調用在哪個上下文中執(zhí)行的問題。這種軟件架構唯一流行的地方是沒有用戶和虛擬內存的嵌入式系統(tǒng)和網絡路由器。

          虛擬內存的問題使得實現(xiàn)內核上行調用機制的問題更加復雜。分配給用戶進程的內存是虛擬內存,但網絡接口等設備使用的內存是物理內存。讓內核將物理內存從設備映射到用戶空間,打破了虛擬內存系統(tǒng)提供的基本保護。

          面對挑戰(zhàn)的嘗試與猜想

          為了克服socket API 中存在的性能問題,有幾種不同的機制,有時在不同的操作系統(tǒng)上實現(xiàn)了這些機制。

          低延遲的網絡應用

          對于那些更關心延遲的程序而言,所做的工作很少。對于正在等待網絡事件的程序來說,唯一重要的改進是添加了一組程序可以等待的內核事件,實現(xiàn)異步通知機制。例如 kevents () 是 select ()機制的擴展,它包含了內核可能告訴程序的任何可能的事件。在 kevents ()出現(xiàn)之前,用戶程序可以在任何文件描述符上調用 select () ,這樣程序就可以知道一組文件描述符中的任何一個是可讀的、可寫的,或者有錯誤。當程序被寫入一個循環(huán)并等待一組文件描述符時,例如從網絡讀取并寫入磁盤ー select ()調用就足夠了,但是一旦程序想檢查其他事件,例如計時器和信號,select ()就無能為力了。低延遲應用程序的問題在于 kevents ()不傳遞數(shù)據(jù),只傳遞數(shù)據(jù)就緒的信號。下一個邏輯步驟是使用基于事件的 API 來傳遞數(shù)據(jù)。為了獲得內核知道應用程序需要的數(shù)據(jù),讓應用程序兩次跨越用戶/內核邊界是沒有道理的。

          高帶寬的網絡應用

          因為復制數(shù)據(jù)會降低網絡協(xié)議的性能,其中一種機制是零拷貝socket,為了提高對高帶寬更感興趣的網絡應用程序速度,對操作系統(tǒng)進行了修改,以避免更多的數(shù)據(jù)副本。

          傳統(tǒng)上,操作系統(tǒng)對系統(tǒng)接收到的每個數(shù)據(jù)包執(zhí)行兩個副本。第一個拷貝由網絡驅動程序從網絡設備的內存中執(zhí)行到內核的內存中,第二個拷貝由內核中的socket層在用戶程序讀取數(shù)據(jù)時執(zhí)行。系統(tǒng)接收到的每個消息都要執(zhí)行拷貝,導致這些復制操作的成本都較高。同理,當程序想要發(fā)送一條消息時,必須將發(fā)送的每條消息的數(shù)據(jù)從用戶程序復制到內核; 然后再被復制到設備用來在網絡上傳輸?shù)木彌_區(qū)中。

          數(shù)據(jù)復制對系統(tǒng)性能是一種詛咒,可以努力在內核中最小化這種復制。內核避免數(shù)據(jù)拷貝的最簡單方法是讓設備驅動程序將數(shù)據(jù)直接復制到內核內存中或從內核內存中復制出來。在現(xiàn)代網絡的設備上,這是如何構建內存的結果。驅動程序和內核共享兩個分組描述符環(huán)(一個用于發(fā)送,一個用于接收) ,其中每個描述符都有一個指向內存的指針。網絡設備驅動程序最初用內核的內存填充這些發(fā)送/接收環(huán)。當接收到數(shù)據(jù)時,設備在正確的接收描述符中設置一個標志,通常通過中斷告訴內核有數(shù)據(jù)等待。然后,內核從接收描述符環(huán)中刪除已填充的緩沖區(qū),并將其替換為新的緩沖區(qū),以便設備填充。數(shù)據(jù)包以緩沖區(qū)的形式在網絡堆棧中移動,直到到達套接字層,當用戶的程序調用 read ()時,數(shù)據(jù)包從內核中復制出來。程序發(fā)送的數(shù)據(jù)由內核以類似的方式處理,內核緩沖區(qū)最終被添加到傳輸描述符環(huán)中,然后設置一個標志來告訴設備它可以將數(shù)據(jù)放在網絡上的緩沖區(qū)中。

          內核中的所有這些工作都沒有解決最后那個拷貝的問題,仍然是跨用戶/內核邊界安全地共享內存。內核無法將其內存提供給用戶程序,因為這時它將失去對內存的控制。崩潰的用戶程序可能會使內核失去大量可用內存,從而導致系統(tǒng)性能下降??鐑群?用戶邊界共享內存緩沖區(qū)也存在固有的安全問題。此時,對于如何使用 sockets API 實現(xiàn)更高的帶寬,暫時沒有單一的答案。

          多宿主的網絡應用

          socket API 不僅在應用程序編寫上存在性能問題,而且還減少了可能發(fā)生的通信類型??蛻魴C/服務器模式本質上是點對點的通信類型。雖然服務器可以處理來自不同客戶機組的請求,但是每個客戶機對于一個請求或一組請求只有一個到單個服務器的連接。在一個每臺計算機只有一個網絡接口的世界里,這種模式非常合理??蛻魴C和服務器之間的連接由?< 源 IP,源端口,目標 IP,目標端口 >?來標識。由于服務通常有一個眾所周知的目標端口(例如,HTTP 的目標端口為80) , IP 地址是固定的,所以唯一可以容易改變的值是源端口。

          在socket API誕生的年代,每臺不是路由器的計算機只有一個網絡接口,這意味著為了識別一個服務,客戶端計算機需要一個目的地址和端口,而它本身只有一個源地址和端口。一臺計算機用多種方式獲得服務的想法過于復雜,而且實現(xiàn)起來成本太高??紤]到這些限制,sockets API 沒有理由向程序員展示編寫多宿主程序的能力,這樣的呈現(xiàn)可以管理對其重要的接口或連接。這些特性在實現(xiàn)時是操作系統(tǒng)中路由軟件的一部分。程序最終能夠訪問它們的唯一途徑是通過一組名為路由套接字(routing socket)的非標準內核 API。

          在具有多個網絡接口的系統(tǒng)上,使用標準的Socket API 編寫一個可以輕松地多網址址的應用程序是不可能的。如果那樣的話,在利用這兩個接口時,如果其中一個出現(xiàn)故障,或者如果數(shù)據(jù)包流經的主要路由出現(xiàn)故障,應用程序不會失去與服務器的連接。

          盡管SCTP 在協(xié)議級別集成了對多宿主的支持,但是不可能通過socket API 導出這種支持。最初提供了幾個臨時系統(tǒng)調用,這是訪問這一功能的唯一方法。到目前為止,這可能是唯一一個同時具有這個特性的能力和用戶需求的協(xié)議,但這個 API 還沒有在多個操作系統(tǒng)中標準化。下表列出了 SCTP 添加的API:

          sctp_bindx()將 SCTP socket綁定或取消綁定到地址列表
          sctp_connectx()使用多個目標地址連接 SCTP socket
          sctp_generic_recvmsg()從對等點接收數(shù)據(jù)
          sctp_generic_sendmsg()將數(shù)據(jù)發(fā)往對等點
          sctp_getaddrlen()返回地址族的地址長度
          sctp_getassocid()返回指定socket地址的關聯(lián) ID
          ctp_getpaddrs()<將地址列表返回給調用者
          sctp_peeloff()將關聯(lián)從一對多套接字分離到單獨的文件描述符
          ctp_getpaddrs()將地址列表返回給調用者
          sctp_sendx()?從 SCTP 套接字發(fā)送消息
          sctp_sendmsgx()?從 SCTP 套接字發(fā)送消息

          雖然這個函數(shù)列表超過了API必需的數(shù)量,但需要注意的是,許多函數(shù)都是socket api 的衍生品,例如 send () ,需要擴展才能在一個多宿主的世界中工作?,F(xiàn)在的問題是Socket API無處不在,以至于很難改變現(xiàn)有的 API 集合,害怕混淆用戶或者已有的應用程序。

          隨著系統(tǒng)內置了越來越多的網絡接口,編寫利用多宿主應用程序的能力將是必要的。很容易地想象這種技術在智能手機中的應用,智能手機有三個顯然的網絡接口: 通過蜂窩網絡的接口,WiFi 接口,通常還有一個藍牙接口。如果哪怕只有一個網絡接口正常工作,應用程序也不應該失去連接性。應用程序設計者的問題在于,希望自己的代碼能夠在很少或沒有任何變化的情況下,通過大量的設備工作,從手機到筆記本電腦,再到臺式機等等。有了正確定義的API,就可以移除阻止這種情況發(fā)生。只是由于 socket API “足夠好”的事實,這種需求尚未得到滿足。

          小結

          對高帶寬、低延遲和多宿主的支持是socket API 需要面對的挑戰(zhàn)。局域網現(xiàn)在已經達到10 Gbps,對于許多應用程序來說,客戶機/服務器風格的通信效率太低,可能無法高效使用可用的帶寬。擴展socket API 支持的通信范例,以允許跨內核邊界共享內存,允許將數(shù)據(jù)傳送到應用程序的低延遲機制。另外,因為具有多個主動接口的設備正在成為網絡系統(tǒng)的標準,多宿主的支持也應該成為socket API 的一個特性。


          【關聯(lián)閱讀】

          瀏覽 71
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  老司机福利在线视频 | 久久99久久久久久久久久久 | 九九热视频精品在线 | 婷婷五月丁香五月 | 欧美精品手机在线观看 |