日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

uTorrent transport protocol

發(fā)布時(shí)間:2024/3/26 65 豆豆
生活随笔 收集整理的這篇文章主要介紹了 uTorrent transport protocol 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

uTorrent Transport Protocol

  • 設(shè)計(jì)人員
  • 產(chǎn)生背景
  • 總體介紹
  • 頭部格式
      • type
      • version
      • connection_id
      • timestamp_microseconds
      • timestamp_difference_microseconds
      • wnd_size
      • seq_nr
      • ack_nr
      • extension
        • SELECTIVE ACK
  • 建立連接
  • 包丟失
  • 超時(shí)
  • 包大小
  • 擁塞控制

設(shè)計(jì)人員

uTorrent傳輸協(xié)議由Ludvig Strigeus,Greg Hazel,Stanislav Shalunov,Arvid Norberg和Bram Cohen設(shè)計(jì)。

產(chǎn)生背景

uTP的起源動(dòng)機(jī)是讓BitTorrent客戶(hù)端不會(huì)中斷互聯(lián)網(wǎng)連接,同時(shí)仍然充分利用未使用的帶寬。

問(wèn)題是DSL和電纜調(diào)制解調(diào)器通常具有與其最大發(fā)送速率不成比例的發(fā)送緩沖器,其可以容納幾秒鐘的數(shù)據(jù)包。BitTorrent流量通常是后臺(tái)傳輸,應(yīng)該比檢查電子郵件,電話和瀏覽網(wǎng)頁(yè)的優(yōu)先級(jí)低,但是當(dāng)使用常規(guī)TCP連接時(shí),BitTorrent會(huì)快速填滿(mǎn)發(fā)送緩沖區(qū)(多并發(fā)連接),為所有交互式流量增加多秒延遲。

BitTorrent使用多個(gè)TCP連接這一事實(shí)使其在與其他服務(wù)競(jìng)爭(zhēng)帶寬時(shí)具有不公平的優(yōu)勢(shì),這夸大了BitTorrent填充上傳管道的影響。這是因?yàn)門(mén)CP在連接中均勻分配可用帶寬,并且一個(gè)應(yīng)用程序使用的連接越多,它所獲得的帶寬份額就越大。

這個(gè)問(wèn)題的傳統(tǒng)解決方案是將BitTorrent客戶(hù)端的上傳速率限制在上行鏈路容量的80%。80%為交互式交通留下了一些空間。

該解決方案的主要缺點(diǎn)是:

  • 用戶(hù)需要配置他/她的BitTorrent客戶(hù)端,它不會(huì)開(kāi)箱即用。
  • 用戶(hù)需要知道他/她的互聯(lián)網(wǎng)連接的上傳容量。此容量可能會(huì)發(fā)生變化,尤其是在可能連接到大量不同網(wǎng)絡(luò)的筆記本電腦上。
  • 20%的凈空是任意的,浪費(fèi)帶寬。每當(dāng)沒(méi)有交互式流量與BitTorrent競(jìng)爭(zhēng)時(shí),額外的20%就會(huì)被浪費(fèi)掉。每當(dāng)存在競(jìng)爭(zhēng)性交互流量時(shí),它就不能使用超過(guò)20%的容量。
  • uTP通過(guò)使用調(diào)制解調(diào)器隊(duì)列大小作為其發(fā)送速率的控制器來(lái)解決此問(wèn)題。當(dāng)隊(duì)列變得太大時(shí),它會(huì)限制回來(lái)。

    這使得它可以在沒(méi)有競(jìng)爭(zhēng)的情況下利用完整的上傳容量,并且當(dāng)有大量交互流量時(shí),它可以讓它減少到幾乎沒(méi)有。

    總體介紹

    本文檔假設(shè)您了解TCP和基于窗口的擁塞控制的工作原理。

    uTP是一種在UDP之上分層的傳輸協(xié)議。因此,它必須(并且有能力)實(shí)現(xiàn)自己的擁塞控制。

    與TCP相比的主要區(qū)別是基于延遲的擁塞控制。請(qǐng)參閱擁塞控制部分。

    與TCP一樣,uTP使用基于窗口的擁塞控制。每個(gè)socket具有一個(gè)max_window,其決定在任何給定的時(shí)間,socket可以具有處于 in-flight 狀態(tài)的最大字節(jié)數(shù)。已發(fā)送但尚未確認(rèn)的任何數(shù)據(jù)包都被視為處于 in-flight 狀態(tài),處于 in-flight 狀態(tài)的字節(jié)數(shù)被定義為 cur_window。

    只有在 cur_window + packet_size <= min(max_window,wnd_size),socket 允許發(fā)送數(shù)據(jù)包。數(shù)據(jù)包大小可能會(huì)有所不同,請(qǐng)參閱數(shù)據(jù)包大小部分。wnd_size是對(duì)端的建議窗口。它設(shè)定了對(duì)端處于 in-flight 狀態(tài)的數(shù)據(jù)包數(shù)量上限。

    如果 max_window 小于數(shù)據(jù)包大小,則實(shí)現(xiàn)可能違反上述規(guī)則,并且它會(huì)調(diào)度數(shù)據(jù)包以使平均 cur_window <= max_window。

    每個(gè)socket記錄來(lái)自對(duì)端的最后一次延遲測(cè)量的狀態(tài)(reply_micro)。無(wú)論何時(shí)收到數(shù)據(jù)包,都會(huì)通過(guò)從主機(jī)當(dāng)前時(shí)間減去timestamp_microseconds字段值(參閱頭部格式部分)來(lái)更新此狀態(tài)(以微秒為單位)。每次發(fā)送數(shù)據(jù)包時(shí),socket 的reply_micro值都會(huì)放入數(shù)據(jù)包標(biāo)頭的timestamp_difference_microseconds字段中。

    與TCP不同,uTP中的序列號(hào)和ACK指的是數(shù)據(jù)包,而不是字節(jié)。這意味著uTP 在重新發(fā)送時(shí)無(wú)法重新打包數(shù)據(jù)。

    每個(gè)socket會(huì)記錄發(fā)送數(shù)據(jù)包時(shí)要使用的下一個(gè)序列號(hào)seq_nr。它還記錄上次接收的序列號(hào)ack_nr。最舊的未確認(rèn)的數(shù)據(jù)包是seq_nr - cur_window。

    頭部格式

    version 1 頭部:

    所有字段都按網(wǎng)絡(luò)字節(jié)順序(大端)。

    type

    type字段描述了數(shù)據(jù)包的類(lèi)型。它可以是以下之一:

    • ST_DATA = 0
      常規(guī)數(shù)據(jù)包。套接字處于連接狀態(tài)并具有要發(fā)送的數(shù)據(jù)。ST_DATA數(shù)據(jù)包始終具有數(shù)據(jù)有效負(fù)載。

    • ST_FIN = 1
      終止連接。這是最后一個(gè)數(shù)據(jù)包。類(lèi)似于TCP FIN標(biāo)志,關(guān)閉連接。屬于該連接的數(shù)據(jù)包,序列號(hào)永遠(yuǎn)不會(huì)有大于此數(shù)據(jù)包中的序列號(hào)。socket將此序列號(hào)記錄為eof_pkt。即使在收到ST_FIN數(shù)據(jù)包后,socket仍會(huì)等待一段時(shí)間,接收那些可能是丟失的或亂序到達(dá)的數(shù)據(jù)包。

    • ST_STATE = 2
      狀態(tài)包。用于傳輸沒(méi)有數(shù)據(jù)的ACK。不包含任何有效負(fù)載的數(shù)據(jù)包不會(huì)增加seq_nr。

    • ST_RESET = 3
      強(qiáng)行終止連接。與TCP RST標(biāo)志類(lèi)似。遠(yuǎn)程主機(jī)沒(méi)有此連接的任何狀態(tài),標(biāo)識(shí)它是陳舊的,應(yīng)該被終止。

    • ST_SYN = 4
      連接SYN。與TCP SYN標(biāo)志類(lèi)似,此數(shù)據(jù)包啟動(dòng)連接。序列號(hào)初始化為1。connection ID 初始化為隨機(jī)數(shù)。syn數(shù)據(jù)包是特殊的,在此連接上發(fā)送的所有后續(xù)數(shù)據(jù)包(除了重新發(fā)送的ST_SYN)都使用(connection ID + 1)發(fā)送。connection ID 是另一端在其響應(yīng)中使用的。

      當(dāng)接收到ST_SYN時(shí),應(yīng)使用包頭中的ID初始化新socket。應(yīng)將socket的發(fā)送ID初始化為ID + 1。返回通道的序列號(hào)初始化為隨機(jī)數(shù)。另一端期望收到響應(yīng)ST_STATE包(僅ACK)。

    version

    協(xié)議版本。目前的版本是1。

    connection_id

    這是一個(gè)隨機(jī)的唯一編號(hào),用于標(biāo)識(shí)屬于同一連接的所有數(shù)據(jù)包。每個(gè)socket都有一個(gè)用于發(fā)送數(shù)據(jù)包的連接ID和用于接收數(shù)據(jù)包的不同連接ID。啟動(dòng)連接的端點(diǎn)決定使用哪個(gè)ID,返回路徑具有相同的ID + 1。

    timestamp_microseconds

    這是發(fā)送此數(shù)據(jù)包的時(shí)間戳的“微秒”部分。這是在posix上使用gettimeofday()和在windows上使用QueryPerformanceTimer()設(shè)置的。時(shí)間戳精度越高越好,時(shí)間戳設(shè)定越接近實(shí)際傳輸時(shí)間越好。

    timestamp_difference_microseconds

    這是收到最新的一個(gè)數(shù)據(jù)包時(shí),數(shù)據(jù)包的時(shí)間戳和本地時(shí)間之間的差值。這是從遠(yuǎn)端到本地的鏈路最新單向延遲測(cè)量。

    當(dāng)新打開(kāi)socekt并且還沒(méi)有任何延遲樣本時(shí),必須將其設(shè)置為0。

    wnd_size

    通知接收窗口。這是32位寬,以字節(jié)為單位指定。

    window size是指當(dāng)前正在傳輸?shù)淖止?jié)數(shù),即已發(fā)送但未被確認(rèn)ACK。當(dāng)接收緩沖區(qū)即將被填滿(mǎn)時(shí),如果它不能更快??地接收,則通知接收窗口可以讓另一端修改窗口大小。

    發(fā)送數(shù)據(jù)包時(shí),應(yīng)將其設(shè)置為socket接收緩沖區(qū)中剩余的字節(jié)數(shù)。

    seq_nr

    這是該數(shù)據(jù)包的序列號(hào)。與TCP相反,uTP序列號(hào)不是指字節(jié),而是指數(shù)據(jù)包。序列號(hào)告訴另一端應(yīng)該將數(shù)據(jù)包送回應(yīng)用層的順序。

    ack_nr

    這是數(shù)據(jù)包的發(fā)送者最后在對(duì)端接收的序列號(hào)。

    extension

    擴(kuò)展鏈表中第一個(gè)擴(kuò)展的類(lèi)型。0表示沒(méi)有擴(kuò)展名。

    目前有一個(gè)擴(kuò)展:

  • Selective acks
  • 擴(kuò)展是鏈接形式的,就像TCP options一樣。如果擴(kuò)展字段非零,則緊跟在uTP頭之后是兩個(gè)字節(jié):

    其中extension指定鏈表中下一個(gè)擴(kuò)展的類(lèi)型,0終止列表。len指定這個(gè)擴(kuò)展的字節(jié)數(shù)。只需向前l(fā)en個(gè)字節(jié)就可以跳過(guò)未知的擴(kuò)展名。

    SELECTIVE ACK

    Selective ACK是一種非順序的、可選擇性的ACK包擴(kuò)展。其有效載荷是至少32位的位掩碼,長(zhǎng)度是32位的倍數(shù)。每個(gè)位代表發(fā)送窗口中的一個(gè)數(shù)據(jù)包。發(fā)送窗口之外的位將被忽略。設(shè)置位(1)指定已接收數(shù)據(jù)包,清除位(0)指定尚未接收數(shù)據(jù)包。頭部格式如下:

    請(qǐng)注意,擴(kuò)展名的len字段指的是字節(jié),在此擴(kuò)展名中必須至少為4,并且為4的倍數(shù)。

    僅當(dāng)在接收的流中跳過(guò)至少一個(gè)序列號(hào)時(shí)才發(fā)送選擇性ACK。因此,掩碼中的第一個(gè)比特表示ack_nr + 2。當(dāng)發(fā)送該包時(shí),則ack_nr + 1被假設(shè)為已被丟棄或丟失。設(shè)置位表示已接收的數(shù)據(jù)包,清除位表示尚未接收的數(shù)據(jù)包。

    位掩碼具有反向字節(jié)順序。第一個(gè)字節(jié)以相反的順序表示包[ack_nr + 2,ack_nr + 2 + 7]。字節(jié)中的最低有效位表示ack_nr + 2,字節(jié)中的最高有效位表示ack_nr + 2 + 7。掩碼中的下一個(gè)字節(jié)以相反的順序表示[ack_nr + 2 + 8,ack_nr + 2 + 15],等等。位掩碼不限于32位,而是可以是任何大小。

    以下是位掩碼的布局,表示在Selective ACK位域中表示的前32個(gè)包的acks:

    圖中的數(shù)字將位掩碼中的位映射到偏移量,然后加上 ack_nr來(lái)計(jì)算該位要確認(rèn)的序列號(hào)。

    建立連接

    下圖說(shuō)明了啟動(dòng)連接的通信和狀態(tài)。c.*指的是socket本身的狀態(tài),pkt.*指的是包頭中的字段。

    連接由conn_id標(biāo)頭標(biāo)識(shí)。如果新連接的連接ID與現(xiàn)有連接沖突,則連接嘗試將失敗,因?yàn)镾T_SYN數(shù)據(jù)包在現(xiàn)有流中將是異常的,并被忽略。

    包丟失

    如果序列號(hào)(seq_nr - cur_window)的數(shù)據(jù)包尚未被確認(rèn)(這是發(fā)送緩沖區(qū)中最早的數(shù)據(jù)包,也是需要被確認(rèn)的下一個(gè)數(shù)據(jù)包),但跳過(guò)該數(shù)據(jù)包之后的3個(gè)或更多數(shù)據(jù)包已被確認(rèn)(通過(guò)Selective ACK),則假設(shè)該數(shù)據(jù)包丟失了。類(lèi)似地,當(dāng)接收到3個(gè)重復(fù)的ack時(shí),假設(shè)ack_nr + 1已經(jīng)丟失(如果已經(jīng)發(fā)送了具有該序列號(hào)的數(shù)據(jù)包)。

    這也適用于Selective ACK。在選擇性確認(rèn)消息中被確認(rèn)的每個(gè)包被計(jì)為一個(gè)重復(fù)的ack,如果它>=3,則在其之后的具有>=3個(gè)被確認(rèn)的數(shù)據(jù)包都應(yīng)該被重新發(fā)送。

    當(dāng)數(shù)據(jù)包丟失時(shí),max_window乘以0.5以模擬TCP。

    超時(shí)

    通過(guò)落入范圍(last_ack_nr,ack_nr] 或明確地被Selective ACK消息被確認(rèn)的每個(gè)數(shù)據(jù)包都應(yīng)該用于更新rtt(往返時(shí)間)和rtt_var(rtt方差)測(cè)量。這里的 last_ack_nr 是 socket 在當(dāng)前數(shù)據(jù)包之前收到的最后一個(gè)ack_nr,ack_nr是當(dāng)前數(shù)據(jù)包中的字段。

    該 rrt 和 rtt_var 只更新已發(fā)送且只發(fā)送了一次的數(shù)據(jù)包。這避免了需要知道是哪個(gè)數(shù)據(jù)包被確認(rèn)的問(wèn)題,第一個(gè)或第二個(gè)數(shù)據(jù)包。

    每次確認(rèn)數(shù)據(jù)包時(shí),rtt 和 rtt_var 都由以下公式計(jì)算:

    delta = rtt - packet_rtt rtt_var +=(abs(delta) - rtt_var) / 4; rtt += (packet_rtt - rtt) / 8;

    每次更新 rtt 和 rtt_var 時(shí),也會(huì)更新與socket關(guān)聯(lián)的數(shù)據(jù)包的默認(rèn)超時(shí) 。它被設(shè)置為:

    timeout = max(rtt + rtt_var * 4, 500);

    其中timeout以毫秒為單位指定。即數(shù)據(jù)包的最小超時(shí)為1/2秒。

    每次socket發(fā)送或接收數(shù)據(jù)包時(shí),它都會(huì)更新其timeout計(jì)數(shù)器。如果從上一次timeout計(jì)數(shù)器重置開(kāi)始,在timeout毫秒內(nèi)沒(méi)有數(shù)據(jù)包到達(dá),則socket觸發(fā)超時(shí)。它將 packet_size 和 max_window 設(shè)置為最小的數(shù)據(jù)包大小(150字節(jié))。這允許它再發(fā)送一個(gè)數(shù)據(jù)包,這就是如果窗口大小降到零,套接字再次啟動(dòng)的方式。

    初始超時(shí)設(shè)置為1000毫秒,稍后根據(jù)上面的公式進(jìn)行更新。對(duì)于超時(shí)的數(shù)據(jù)包以及后續(xù)的每個(gè)數(shù)據(jù)包,超時(shí)加倍。

    包大小

    為了盡可能減少對(duì)慢速擁塞鏈路的影響,uTP將其數(shù)據(jù)包大小調(diào)整為每個(gè)數(shù)據(jù)包150個(gè)字節(jié)。使用較小的數(shù)據(jù)包具有不會(huì)阻塞慢速上行鏈路的優(yōu)點(diǎn),具有較長(zhǎng)的序列化延遲。使用小數(shù)據(jù)包的成本使得數(shù)據(jù)包報(bào)頭的開(kāi)銷(xiāo)變得很大。在高速率下,使用大的包大小,慢速率下使用小的包大小。

    擁塞控制

    uTP擁塞控制的總體目標(biāo)是使用單向緩沖延遲作為主要擁塞測(cè)量,丟包也是如此,和TCP類(lèi)似。關(guān)鍵是要避免在發(fā)送數(shù)據(jù)時(shí)使用全部的發(fā)送緩沖區(qū)運(yùn)行。這對(duì)于DSL / Cable調(diào)制解調(diào)器來(lái)說(shuō)尤其是一個(gè)問(wèn)題,其中調(diào)制解調(diào)器中的發(fā)送緩沖器通常具有多秒數(shù)據(jù)的空間。uTP(或任何后臺(tái)流量協(xié)議)的理想緩沖區(qū)利用率是以0字節(jié)緩沖區(qū)利用率運(yùn)行。即任何其他流量可以在任何時(shí)間發(fā)送而不受阻礙。實(shí)際上,uTP目標(biāo)延遲設(shè)置為100 ms。每個(gè)socket的目的是永遠(yuǎn)不會(huì)在發(fā)送鏈路上看到超過(guò)100毫秒的延遲,如果有,它會(huì)減速。這有效地使uTP流量屈服于任何TCP流量。

    這是通過(guò)在uTP發(fā)送的每個(gè)數(shù)據(jù)包中包含高精度時(shí)間戳來(lái)實(shí)現(xiàn)的,并且接收端計(jì)算其自己的高精度計(jì)時(shí)器與其接收的數(shù)據(jù)包中的時(shí)間戳之間的差異。然后將該差異反饋給包的原始發(fā)送方(timestamp_difference_microseconds)。該值作為絕對(duì)值沒(méi)有意義。機(jī)器中的時(shí)鐘很可能不同步,尤其是不低于微秒分辨率,并且數(shù)據(jù)包在傳輸?shù)臅r(shí)間也包含在這些時(shí)間戳的差異中。但是,與以前的timestamp_difference_microseconds值相比,該值很有用。

    每個(gè)socket記錄在最后兩分鐘內(nèi)的滑動(dòng)最小值。此值稱(chēng)為base_delay,用作基線,即主機(jī)之間的最小延遲。當(dāng)從每個(gè)數(shù)據(jù)包中的時(shí)間戳差異中減去base_delay時(shí),您將獲得socket上當(dāng)前緩沖延遲的度量。此測(cè)量稱(chēng)為our_delay。它有很多噪音,但用作驅(qū)動(dòng)程序來(lái)確定是增加還是減少發(fā)送窗口(控制發(fā)送速率)。

    CCONTROL_TARGET是UTP接受上行鏈路上的緩沖延遲。目前,延遲目標(biāo)設(shè)置為100毫秒。off_target是實(shí)際測(cè)量延遲距目標(biāo)延遲的距離(從CCONTROL_TARGET - our_delay計(jì)算得出)。

    socket結(jié)構(gòu)中的窗口大小指定了連接上我們可能在in_flight中(未確認(rèn))的字節(jié)數(shù)。發(fā)送速率與此窗口大小直接相關(guān)。飛行中的字節(jié)越多,發(fā)送速率越快。在代碼中,窗口大小稱(chēng)為 max_window。它的大小大致由以下表達(dá)式控制:

    delay_factor = off_target / CCONTROL_TARGET; window_factor = outstanding_packet / max_window; scaled_gain = MAX_CWND_INCREASE_PACKETS_PER_RTT * delay_factor * window_factor;

    第一個(gè)因子將off_target縮放到目標(biāo)延遲的單位。

    然后將scaled_gain添加到max_window:

    max_window += scaled_gain;

    如果off_target大于0,這將使窗口變小,如果off target小于0,則增大窗口。

    如果max_window小于0,則將其設(shè)置為0。窗口大小為零意味著socket可能不發(fā)送任何數(shù)據(jù)包。在此狀態(tài)下,socekt將觸發(fā)超時(shí)并將窗口大小強(qiáng)制為一個(gè)數(shù)據(jù)包大小,并發(fā)送一個(gè)數(shù)據(jù)包。有關(guān)更多信息,請(qǐng)參閱有關(guān)超時(shí)的部分。

    總結(jié)

    以上是生活随笔為你收集整理的uTorrent transport protocol的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。