套接字中缓冲区
原博文地址:
https://www.cnblogs.com/justkong/p/7657363.html
套接字中緩沖區
1、MTU(Maximum Transmission Unit)
最大傳輸單元,在數據鏈路層中,往往規定了MTU大小,IP層的數據包通過數據鏈路層如果大于MTU,將被分片,到達接收端IP層后再被重組。以太網的MTU為1500字節。
2、MSS(Maximum Segment Size)
最大報文段,是TCP協議的一個選項。MSS選項用于在TCP建立連接時,收發雙方協商一個TCP報文段所能承載的最大數據長度。MSS選項只在初始化連接請求(SYN=1)的報文段中使用。選擇合適的MSS很重要。如果MSS小了,網絡利用率低。如果MSS大了,由于在網絡層需要分片,也會影響網絡性能。一般MSS的長度為MTU(1500)-IP首部(20)-TCP首部(20)=1460字節。
3、TCP的緩沖區
如上圖所示,每一個TCP套接字都有一個發送緩沖區,可以使用SO_SNDBUF套接字選項來更改緩沖區大小。我們調用send發送數據的時候(默認阻塞模式),如果緩沖區沒滿,調用直接返回。但是這僅僅表明數據被復制到緩沖區中,并不表明對端接收到數據。系統內核在IP層發送數據的時候,并不是按照我們調用send接口發送的數據包大小來進行發送,即使我們調用send發送的數據大小小于1460字節(MTU-TCP首部-IP首部)。因為我們調用send接口實際是將數據復制到緩沖區中,而內核基本上是按照最大MSS大小(1460字節)從緩沖區中取數據發送出去,當緩沖區中數據小于MSS,則將剩余數據全部發送出去。TCP的發送緩沖區必須為已發送的數據保留一個副本,直到它被對端確認為止,才能從緩沖區中刪掉已確認的數據。
TCP接收緩沖區,可以通過SO_RCVBUF套接字選項來更改。接收緩沖區被TCP用來保存接收到的數據,直到應用程序來讀取。對于TCP來說,接收緩沖區中可用空間的大小限定了TCP通告對端的窗口大小。TCP套接字的接收緩沖區不能溢出,所以發送端不能發送超過接收端通知的窗口大小,否則在接收端將丟棄數據包。
4、UDP的緩沖區
UDP也有發送緩沖區大小,也可以通過SO_SNDBUF套接字選項更改它,不過它不同于TCP的發送緩沖區大小,它僅僅是可以寫到該套接字的UDP數據報的大小上限。如果一個應用程序寫一個大于套接字發送緩沖區大小的數據報,內核將返回一個EMSGSIZE錯誤。UDP緩沖區中數據被發送完之后,該數據就被刪除了。我們調用sendto發送數據的時候,內核在收到用戶的數據報,僅僅給數據包加上8字節的首部構成UDP數據報,然后就傳給IP層。如果數據報大小小于MTU,則直接發送給對端;如果大于MTU,則會被分片。所以通過UDP協議發送數據報,應該考慮發送的數據包小于MTU-8(UDP首部)-20(IP首部),這樣在通過IP層就不用分片,丟包率將比分片處理的情況小很多。
UDP的接收緩沖區,同樣通過SO_RCVBUF套接字選項更改它。當接收到的數據報裝不進接收緩沖區,該數據報就被丟棄。
5、TCP緩沖區的調用順序
當設置TCP套接字緩沖區大小時,函數的調用順序很重要。因為TCP的窗口規模選項是在建立連接時用SYN分節與對端互換得到的。對于客戶端,這意味著緩沖區選項必須在調用connect之前設置。對于服務端,這意味著該選項必須在調用listen之前給監聽套接字設置,已連接套接字的緩沖區大小總是從監聽套接字繼承而來。
6、TCP套接字緩沖區的性能
在設置套接字緩沖區大小時需要考慮性能問題。下圖展示了兩個端點間容量為8個分節的一個TCP連接(稱其為管道)。
我們在頂部給出4個數據分節,在底部給出4個ACK。即使管道中只有4個數據分節,客戶端也必須有至少8個分節容量的發送緩沖區,因為客戶端TCP必須為每個分節保留一個副本,直到接收到來自服務器的相應ACK。這里涉及管道容量的概念,稱為“帶寬-延遲積(bandwidth-delay product)”,它通過將帶寬(bit/s)和RTT(s)相乘,再將結果由位轉換為字節計算得到。其中,RTT可以使用ping程序測得。例如,客戶端到服務端帶寬為100Mb/s,客戶端到服務端RTT為1ms,則帶寬-延遲積為100*1/8為12.5KB。當套接字緩沖區大小小于該值,管道將不會處于滿狀態,性能達不到最高,所以緩沖區一般設置略大于帶寬-延遲積。當帶寬變大或者RTT變大,套接字緩沖區也需要增長。
?
注:以上參考《UNIX網絡編輯卷1》2.11和7.5.8章節
總結
- 上一篇: QML学习笔记-对QML基本认识
- 下一篇: Qt工作笔记-信号与槽参数匹配问题