2008-09-18 73 views

回答

16

在應用程序層(使用Berkeley套接字樣式API),您只需觀察時鐘,然後以您想限制的速率讀取或寫入數據。

如果你只在平均讀取10kbps的,但源發送不止這些,那麼最終所有的IT之間的緩衝區,你將填補。 TCP/IP允許這樣做,並且協議將安排發送者放慢速度(在應用層,可能你所需要知道的是,在另一端阻塞寫入調用將被阻塞,非阻塞寫入將失敗,並且異步寫入不會完成,直到你已經讀取足夠的數據來允許它)。

在應用程序層,您只能近似 - 您不能保證硬限制,例如「不超過10 kb將在任何一秒內通過網絡中的給定點」。但是如果你跟蹤你收到的東西,你可以從長遠來看獲得平均的權利。

4

假設一個網絡傳輸,基於IP的一個TCP /,分組被在響應發送到ACK/NACK數據包正在的其他方式。

通過限制確認收到傳入數據包的數據包的速度,你會反過來抑制用於新的數據包的發送速率。

它可以是一個位不精確,因此,其可能最佳監視下行速率和調整響應速率自適應,直到它落在舒適閾值內。 (然而,這真的很快發生,你發送一秒的ACK)

+0

這不需要轉到低級TCP/IP堆棧,並繞過標準套接字層? – Branan 2008-09-18 18:05:14

1

如果你從一個套接字讀取,你無法控制使用的帶寬 - 你正在讀取該套接字的操作系統的緩衝區,並且你所說的任何話都不會讓寫入套接字的人寫入更少的數據(除非你已經爲此編寫了一個協議)。

緩慢讀取的所有內容都會填滿緩衝區,並導致網絡端發生最終失速 - 但您無法控制發生這種情況的方式或時間。

如果你真的想在一次只讀如此多的數據,你可以做這樣的事情:

ReadFixedRate() { 
    while(Data_Exists()) { 
    t = GetTime(); 
    ReadBlock(); 
    while(t + delay > GetTime()) { 
     Delay()' 
    } 
    } 
} 
+0

緩衝區具有最大值。緩存?沒有涉及緩存。 – 2008-09-18 18:08:14

0

的wget似乎與--limit-rate選項來管理它。下面是從該名男子頁:

注意Wget在網絡閱讀時間比由 率指定 更短的時間後睡覺的時間 適量實現限制 。最終,此策略導致 TCP傳輸大約以指定速率減慢至 。 但是, 可能需要一段時間才能達到此餘額,因此如果限制費率 對於非常小的 文件不起作用,則不會令 感到意外。

0

正如其他人所說,OS內核是管理交通,你只是在讀取數據的副本出的內核內存。要大致限制一個應用程序的速率,您需要延遲讀取數據並允許傳入數據包在內核中緩衝,這最終會減慢對傳入數據包的確認速度,並降低該數據包的速率。

如果您想減慢機器的所有流量,則需要調整傳入TCP緩衝區的大小。在Linux中,您可以通過更改/ proc/sys/net/ipv4/tcp_rmem(讀取內存緩衝區大小)和其他tcp_ *文件中的值來影響此更改。

1

這就像將遊戲限制在一定數量的FPS時一樣。

extern int FPS; 
....  
timePerFrameinMS = 1000/FPS; 

while(1) { 
time = getMilliseconds(); 
DrawScene(); 
time = getMilliseconds()-time; 
if (time < timePerFrameinMS) { 
    sleep(timePerFrameinMS - time); 
} 
} 

這樣您就可以確保遊戲刷新率最高爲FPS。 以同樣的方式DrawScene可以是用於將字節泵入套接字流的函數。

0

爲了增加Branan的回答是:

如果你主動限制在接收端讀取速度,最終隊列將兩端填滿。然後,發送者將阻塞其send()調用或從send()調用中返回,其sent_length小於傳遞給send()調用的預期長度。

如果發件人沒有準備好通過睡眠來處理這種情況並嘗試重新發送不適合OS緩衝區的內容,那麼最終會出現連接問題(發件人可能會將此檢測爲錯誤)或丟失數據(發件人可能會在不知不覺中丟棄不適合OS緩衝區的數據)。

0

設置小插座發送和接收緩衝區,比如說1k或2k,這樣帶寬*延遲乘積=緩衝區大小。您可能無法通過快速鏈接獲得足夠小的空間。