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