最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Bittorrent uTorrent 傳輸協(xié)議

2023-07-24 20:19 作者:IMFile  | 我要投稿

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

設(shè)計(jì)原因

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

BitTorrent 流量通常是后臺(tái)傳輸,其優(yōu)先級(jí)應(yīng)該低于檢查電子郵件,辦公和瀏覽網(wǎng)頁(yè),但是當(dāng)使用常規(guī) TCP 連接時(shí),BitTorrent 會(huì)快速填滿發(fā)送緩沖區(qū),為所有交互式流量增加數(shù)秒的延遲。 BitTorrent 使用多個(gè) TCP 連接的事實(shí)使其在與其他服務(wù)競(jìng)爭(zhēng)帶寬時(shí)具有不公平的優(yōu)勢(shì),這夸大了 BitTorrent 占用上傳帶寬的效果。這樣做的原因是 TCP 在連接之間均勻分配可用帶寬,并且一個(gè)應(yīng)用程序使用的連接越多,它獲得的帶寬份額就越大。

這個(gè)問(wèn)題的傳統(tǒng)解決方案是將 BitTorrent 客戶端的上傳速率限制在上行帶寬容量的 80% 。為其余上下行流量留下了一些空間。此解決方案的主要缺點(diǎn)是:

  1. 用戶需要配置他/她的 BitTorrent 客戶端,它不會(huì)即開(kāi)即用。

  2. 用戶需要知道他/她的互聯(lián)網(wǎng)連接的上限容量。此容量可能會(huì)發(fā)生變化,尤其是在可能連接到大量不同網(wǎng)絡(luò)的筆記本電腦或手機(jī)上。

  3. 20% 的余量是比較隨意的,會(huì)浪費(fèi)帶寬。每當(dāng)沒(méi)有交互式流量與 BitTorrent 競(jìng)爭(zhēng)時(shí),額外的 20% 就會(huì)被浪費(fèi)掉。每當(dāng)存在競(jìng)爭(zhēng)的交互式流量時(shí),它不能只需要使用 20% 的容量。

uTP 通過(guò)使用調(diào)制解調(diào)器隊(duì)列大小作為其發(fā)送速率的控制器來(lái)解決此問(wèn)題。當(dāng)隊(duì)列變得太大時(shí),它會(huì)控制流量。這允許它在沒(méi)有競(jìng)爭(zhēng)時(shí)利用全部上傳容量,并且在有大量交互式流量時(shí)允許它減少到幾乎為零。

概述

本文檔假定讀者對(duì) TCP 和基于窗口的堵塞控制的工作原理有一定的了解。 uTP 是一種分層在 UDP 之上的傳輸協(xié)議。因此,它必須(并且有能力)實(shí)現(xiàn)自己的網(wǎng)絡(luò)堵塞控制。與 TCP 相比,主要區(qū)別在于基于延遲的堵塞控制。

uTP 是建立在 UDP 之上的傳輸協(xié)議,因此它需要自己實(shí)現(xiàn)擁塞控制機(jī)制。與 TCP 相比,uTP 的主要區(qū)別在于基于延遲的擁塞控制。具體細(xì)節(jié)可參考擁塞控制部分的描述。類(lèi)似于 TCP,uTP 采用基于窗口的擁塞控制。每個(gè)套接字都有一個(gè) max_window,用于確定套接字在任何給定時(shí)間內(nèi)可同時(shí)傳輸?shù)淖畲笞止?jié)數(shù)。已發(fā)送但尚未確認(rèn)的任何數(shù)據(jù)包都被認(rèn)為是在傳輸過(guò)程中。

  1. cur_window?表示當(dāng)前傳輸過(guò)程中的字節(jié)數(shù)。只有當(dāng)?cur_window + packet_size?小于等于?min(max_window, wnd_size)時(shí),套接字才能發(fā)送數(shù)據(jù)包。?packet_size?表示數(shù)據(jù)包的大小,可能會(huì)有不同的取值。

  2. wnd_size?是對(duì)方端口所廣告的窗口大小。它設(shè)置了傳輸中的數(shù)據(jù)包數(shù)量的上限。

  3. 如果?max_window?小于數(shù)據(jù)包大小,并且通過(guò)調(diào)整數(shù)據(jù)包傳輸速率使得平均?cur_window?小于等于?max_window,實(shí)現(xiàn)可能違反上述規(guī)則。

  4. 每個(gè)套接字保存了與其他端點(diǎn)的最后一次延遲測(cè)量狀態(tài)(reply_micro)。每當(dāng)接收到一個(gè)數(shù)據(jù)包時(shí),通過(guò)將時(shí)間戳(以微秒為單位)減去主機(jī)當(dāng)前時(shí)間來(lái)更新該狀態(tài)。

  5. 每次發(fā)送數(shù)據(jù)包時(shí),套接字的?reply_micro?值將放置在數(shù)據(jù)包頭部的?timestamp_difference_microseconds?字段中。

  6. 與 TCP 不同,uTP 中的序列號(hào)和 ACK 是基于數(shù)據(jù)包而不是字節(jié)的。這意味著在重新發(fā)送數(shù)據(jù)時(shí),uTP 無(wú)法對(duì)其進(jìn)行重新封裝。

  7. 每個(gè)套接字都保持著下一個(gè)用于發(fā)送數(shù)據(jù)包的序列號(hào)(seq_nr)和上次接收到的數(shù)據(jù)包的序列號(hào)(ack_nr)的狀態(tài)。最老的未確認(rèn)數(shù)據(jù)包序列號(hào)為 seq_nr – cur_window 。

header 格式

版本 1 標(biāo)頭:

0 ? ? ? 4 ? ? ? 8 ? ? ? ? ? ? ? 16 ? ? ? ? ? ? ?24 ? ? ? ? ? ? ?32 +-------+-------+---------------+---------------+---------------+ | type ?| ver ? | extension ? ? | connection_id ? ? ? ? ? ? ? ? | +-------+-------+---------------+---------------+---------------+ | timestamp_microseconds ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| +---------------+---------------+---------------+---------------+ | timestamp_difference_microseconds ? ? ? ? ? ? ? ? ? ? ? ? ? ? | +---------------+---------------+---------------+---------------+ | wnd_size ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| +---------------+---------------+---------------+---------------+ | seq_nr ? ? ? ? ? ? ? ? ? ? ? ?| ack_nr ? ? ? ? ? ? ? ? ? ? ? ?| +---------------+---------------+---------------+---------------+

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

版本

這是協(xié)議版本。當(dāng)前版本為 1 。

connection_id

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

timestamp_microseconds

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

timestamp_difference_microseconds

這是本地時(shí)間與上次接收數(shù)據(jù)包(在收到最后一個(gè)數(shù)據(jù)包時(shí))中的時(shí)間戳之間的差異。這是從遠(yuǎn)程對(duì)等體到本地計(jì)算機(jī)的鏈路的最新單向延遲測(cè)量。當(dāng)套接字是新打開(kāi)的并且還沒(méi)有任何延遲樣本時(shí),必須將其設(shè)置為 0 。

wnd_size?

播發(fā)的接收窗口。這是 32 位寬,以字節(jié)為單位指定。窗口大小是當(dāng)前正在進(jìn)行的字節(jié)數(shù),即已發(fā)送但未確認(rèn)的字節(jié)數(shù)。通告的接收窗口允許另一端限制窗口大小,如果它不能更快地接收,如果它的接收緩沖區(qū)正在填滿。發(fā)送數(shù)據(jù)包時(shí),應(yīng)將其設(shè)置為套接字接收緩沖區(qū)中剩余的字節(jié)數(shù)。

extension?

擴(kuò)展標(biāo)頭鏈接列表中第一個(gè)擴(kuò)展的類(lèi)型。 0 表示無(wú)擴(kuò)展名。

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

  1. 選擇性確認(rèn)

擴(kuò)展是鏈接的,就像 TCP 選項(xiàng)一樣。如果擴(kuò)展字段不為零,則緊跟在 uTP 標(biāo)頭后面的兩個(gè)字節(jié):

0 ? ? ? ? ? ? ? 8 ? ? ? ? ? ? ? 16 +---------------+---------------+ | extension ? ? | len ? ? ? ? ? | +---------------+---------------+

其中?extension?指定鏈表中下一個(gè)擴(kuò)展名的類(lèi)型,0 終止列表。并?len?指定此擴(kuò)展的字節(jié)數(shù)。未知擴(kuò)展可以通過(guò)簡(jiǎn)單地前進(jìn)?len bytes?來(lái)跳過(guò)。

SELECTIVE ACK

選擇性 ACK 是一種擴(kuò)展,可以非順序地選擇性地 ACK 數(shù)據(jù)包。其有效負(fù)載是至少 32 位的位掩碼,以 32 位的倍數(shù)表示。每個(gè)位表示發(fā)送窗口中的一個(gè)數(shù)據(jù)包。發(fā)送窗口之外的位將被忽略。設(shè)置位指定數(shù)據(jù)包已接收,清除位指定數(shù)據(jù)包尚未接收。標(biāo)題如下所示:

0 ? ? ? ? ? ? ? 8 ? ? ? ? ? ? ? 16 +---------------+---------------+---------------+---------------+ | extension ? ? | len ? ? ? ? ? | bitmask +---------------+---------------+---------------+---------------+ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| +---------------+---------------+

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

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

位掩碼的字節(jié)順序相反。第一個(gè)字節(jié)以相反的順序表示數(shù)據(jù)包 [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],依此類(lèi)推。位掩碼不限于 32 位,但可以是任何大小。

下面是位掩碼的布局,表示選擇性 ACK 位域中表示的前 32 個(gè)數(shù)據(jù)包確認(rèn):

0 ? ? ? ? ? ? ? 8 ? ? ? ? ? ? ? 16 +---------------+---------------+---------------+---------------+ | 9 8 ... ? 3 2 | 17 ? ... ? 10 | 25 ? ... ? 18 | 33 ? ... ? 26 | +---------------+---------------+---------------+---------------+

圖中的數(shù)字將位掩碼中的位映射到要添加到?ack_nr?的偏移量,以便計(jì)算位正在確認(rèn)的序列號(hào)。

type

類(lèi)型字段描述數(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ù)包。它關(guān)閉連接,類(lèi)似于 TCP FIN 標(biāo)志。此連接的序列號(hào)永遠(yuǎn)不會(huì)大于此數(shù)據(jù)包中的序列號(hào)。套接字將此序列號(hào)記錄為?eof_pkt?。這允許套接字等待可能仍然丟失的數(shù)據(jù)包,即使在收到 ST_FIN 數(shù)據(jù)包后也會(huì)無(wú)序到達(dá)。

ST_STATE = 2

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

ST_RESET = 3

強(qiáng)制終止連接。類(lèi)似于 TCP RST 標(biāo)志。遠(yuǎn)程主機(jī)沒(méi)有任何此連接的狀態(tài)。它是過(guò)時(shí)的,應(yīng)該終止。

ST_SYN = 4

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

收到 ST_SYN 時(shí),應(yīng)使用數(shù)據(jù)包標(biāo)頭中的 ID 初始化新套接字。套接字的發(fā)送 ID 應(yīng)初始化為 ID + 1 。返回通道的序列號(hào)初始化為隨機(jī)數(shù)。另一端需要 ST_STATE 數(shù)據(jù)包(僅 ACK)作為響應(yīng)。

seq_nr

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

ack_nr

這是數(shù)據(jù)包的發(fā)送方上次在另一個(gè)方向上收到的序列號(hào)。

連接設(shè)置

下圖說(shuō)明了啟動(dòng)連接的交換和狀態(tài)。 c.* 表示套接字本身中的狀態(tài),pkt.* 表示數(shù)據(jù)包標(biāo)頭中的字段。

initiating endpoint ? ? ? ? ? ? ? ? ? ? ? ? ? accepting endpoint ? ? ? ? ?| c.state = CS_SYN_SENT ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| c.seq_nr = 1 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ? ? ? ?| c.conn_id_recv = rand() ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| c.conn_id_send = c.conn_id_recv + 1 ? ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ST_SYN ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ? ? ? ?| ? seq_nr=c.seq_nr++ ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ack_nr=* ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ? ? ? ?| ? conn_id=c.rcv_conn_id ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| >-------------------------------------------> | ? ? ? ? ?| ? ? ? ? ? ? c.receive_conn_id = pkt.conn_id+1 | ? ? ? ? ?| ? ? ? ? ? ? c.send_conn_id = pkt.conn_id ? ? ?| ? ? ? ? ?| ? ? ? ? ? ? c.seq_nr = rand() ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? c.ack_nr = pkt.seq_nr ? ? ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? c.state = CS_SYN_RECV ? ? ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ST_STATE ? ? ? ? ? ? ? ? ?| ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? seq_nr=c.seq_nr++ ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ack_nr=c.ack_nr ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? conn_id=c.send_conn_id ?| ? ? ? ? ?| <------------------------------------------< ?| ? ? ? ? ?| c.state = CS_CONNECTED ? ? ? ? ? ? ? ? ? ? ? ?| ? ? ? ? ?| c.ack_nr = pkt.seq_nr ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ST_DATA ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? seq_nr=c.seq_nr++ ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ack_nr=c.ack_nr ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? conn_id=c.conn_id_send ? ? ? ? ? ? ? ? ? ? ?| ? ? ? ? ?| >-------------------------------------------> | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ?c.ack_nr = pkt.seq_nr ?| ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ?c.state = CS_CONNECTED | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | connection established ? ? .. ..|.. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..|.. .. ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ST_DATA ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? seq_nr=c.seq_nr++ ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ack_nr=c.ack_nr ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? conn_id=c.send_conn_id ?| ? ? ? ? ?| <------------------------------------------< ?| ? ? ? ? ?| c.ack_nr = pkt.seq_nr ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?| ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ?V ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? V

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

丟包

如果序列號(hào)為(?seq_nr?–?cur_window?)的數(shù)據(jù)包尚未確認(rèn)(這是發(fā)送緩沖區(qū)中最早的數(shù)據(jù)包,下一個(gè)數(shù)據(jù)包預(yù)計(jì)被確認(rèn)),但已通過(guò)該數(shù)據(jù)包 3 個(gè)或更多數(shù)據(jù)包(通過(guò)選擇性 ACK),則假定該數(shù)據(jù)包已丟失。同樣,當(dāng)收到 3 個(gè)重復(fù)的確認(rèn)時(shí),?ack_nr?假定 + 1 已丟失(如果已發(fā)送具有該序列號(hào)的數(shù)據(jù)包)。

這也適用于選擇性確認(rèn)。在選擇性確認(rèn)消息中確認(rèn)的每個(gè)數(shù)據(jù)包都計(jì)為一個(gè)重復(fù)的確認(rèn),如果為 3 個(gè)或更多,則應(yīng)觸發(fā)重新發(fā)送至少包含 3 個(gè)數(shù)據(jù)包的數(shù)據(jù)包。

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

超時(shí)

每個(gè)被確認(rèn)的數(shù)據(jù)包,無(wú)論是落在范圍(last_ack_nr 、 ack_nr] 還是被選擇性 ACK 消息顯式確認(rèn),都應(yīng)用于更新(往返時(shí)間)和?rtt?rtt_var?(rtt 方差)測(cè)量值。 last_ack_nr 這里是當(dāng)前數(shù)據(jù)包之前在套接字上收到的最后一個(gè) ack_nr,ack_nr 是當(dāng)前接收的數(shù)據(jù)包中的字段。

僅針對(duì)?rtt?僅發(fā)送一次的數(shù)據(jù)包更新 和?rtt_var?。這避免了確定哪個(gè)數(shù)據(jù)包被確認(rèn)的問(wèn)題,第一個(gè)還是第二個(gè)。

rtt?并通過(guò)?rtt_var?以下公式計(jì)算,每次確認(rèn)數(shù)據(jù)包時(shí):

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

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

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

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

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

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

數(shù)據(jù)包大小

為了盡可能減少對(duì)慢速擁塞鏈路的影響,uTP 將其數(shù)據(jù)包大小調(diào)整為每個(gè)數(shù)據(jù)包 150 字節(jié)。使用這么小的數(shù)據(jù)包的好處是不會(huì)阻塞慢速上行鏈路,并且序列化延遲較長(zhǎng)。使用這么小的數(shù)據(jù)包的代價(jià)是數(shù)據(jù)包標(biāo)頭的開(kāi)銷(xiāo)變得很大。在高速率下,使用大數(shù)據(jù)包大小,在慢速率下,使用小數(shù)據(jù)包大小。

擁塞控制

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

這有效地使 uTP 屈服于任何 TCP 流量。

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

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

CCONTROL_TARGET?是 uTP 在上行鏈路上接受的緩沖延遲。目前,延遲目標(biāo)設(shè)置為 100 毫秒,off_target?實(shí)際測(cè)量的延遲與目標(biāo)延遲的距離(根據(jù)?CCONTROL_TARGET – our_delay?計(jì)算)。

套接字結(jié)構(gòu)中的窗口大小指定了我們?cè)谶B接上總共可能具有的運(yùn)行(未確認(rèn))字節(jié)數(shù)。發(fā)送速率與此窗口大小直接相關(guān)。傳輸中的字節(jié)越多,發(fā)送速率越快。在代碼中,窗口大小稱為?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,這將使窗口變小,如果偏離目標(biāo)小于 0,則窗口增大。

如果 max_window 小于 0,則設(shè)置為 0 。窗口大小為零表示套接字可能不會(huì)發(fā)送任何數(shù)據(jù)包。在此狀態(tài)下,套接字將觸發(fā)超時(shí)并強(qiáng)制窗口大小為一個(gè)數(shù)據(jù)包大小,并發(fā)送一個(gè)數(shù)據(jù)包。有關(guān)詳細(xì)信息,請(qǐng)參閱有關(guān)超時(shí)的部分。

參考鏈接

  • http://www.bittorrent.org/beps/bep_0029.html


Bittorrent uTorrent 傳輸協(xié)議的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
安化县| 桃园市| 上林县| 鲁甸县| 凭祥市| 遵义市| 手游| 凉山| 寻乌县| 盘山县| 和政县| 南宫市| 玉林市| 浠水县| 盐山县| 汉寿县| 临泉县| 甘泉县| 沧州市| 梨树县| 锡林浩特市| 陆川县| 霞浦县| 福鼎市| 嘉禾县| 西充县| 桦川县| 平罗县| 永康市| 巴林左旗| 渝北区| 桐乡市| 伊宁市| 莱西市| 江孜县| 榆树市| 沂源县| 吉林省| 东明县| 休宁县| 郓城县|