www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當前位置:首頁 > > 夜夜生code


導學問題:

1. 增加緩沖區(qū),可以提高程序的吞吐量嗎?
2. 網(wǎng)絡數(shù)據(jù)從發(fā)送到接受的過程,總共拷貝了多少次?

發(fā)送數(shù)據(jù)

ssize_t write (int socketfd, const void *buffer, size_t size)
ssize_t send (int socketfd, const void *buffer, size_t size, int flags)
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags)

這三個都是發(fā)送程序時常用的接口,大部分人可以都很熟悉write函數(shù)了,經(jīng)典的寫文件接口。我們這里重點給大家介紹后兩種。

如果我們想發(fā)送緊急數(shù)據(jù),那么我們就可以使用send接口,給發(fā)送的數(shù)據(jù)加上緊急標記,那么我們的這一幀數(shù)據(jù)就會快速被發(fā)送出去。

如果想指定多重緩沖區(qū)進行數(shù)據(jù)傳輸,就需要使用第三個函數(shù),以結構體msghdr的方式發(fā)送數(shù)據(jù)。

發(fā)送緩沖區(qū)

當tcp連接成功后,在linux內核里面會維護一個發(fā)送緩存區(qū)。它的大小可以通過調整套接字選項來進行設置。當我們應用程序調用write函數(shù)時,實際上是把數(shù)據(jù)從應用程序拷貝到操作系統(tǒng)內核的發(fā)送緩存區(qū),它并不一定馬上就會發(fā)送出去。具體情況如下:

  • 發(fā)送緩存區(qū)足夠大,那么write的系統(tǒng)調用會馬上退出,返回寫入的字節(jié)數(shù)就是應用程序的大小。
  • 發(fā)送緩存區(qū)不足以容納應用程序的數(shù)據(jù),那么write函數(shù)會一直阻塞,直到應用數(shù)據(jù)完全填充到緩存區(qū)后返回,緩存區(qū)的數(shù)據(jù)由操作系統(tǒng)內核負責把它發(fā)送出去。

如下圖:

所以無限增大緩沖區(qū)肯定不行,內核緩沖區(qū)總是充滿數(shù)據(jù)時會產(chǎn)生粘包問題,同時網(wǎng)絡 的傳輸大小MTU也會限制每次發(fā)送的大小,最后由于數(shù)據(jù)堵塞需要消耗大量內存資源,資 源使用效率不高。相當于讓倉庫變大,可以存儲了更多的貨物,如果出貨的速度有限,會有更多的貨物爛在倉庫里。

讀取數(shù)據(jù)

最簡單的數(shù)據(jù)讀取方式就是read函數(shù)了,它的函數(shù)原型如下:

ssize_t read (int socketfd, void *buffer, size_t size)

read函數(shù)要求操作系統(tǒng)內核從套接字描述子socketfd讀取固定數(shù)量的字節(jié),并將讀取的結果存儲到buffer中。返回值告訴我們讀取的實際字節(jié)數(shù)量。特殊情況下,如果它的返回值為0,那么代表EOF,表示網(wǎng)絡中對端發(fā)送了FIN,我們也要相應地進行斷開連接處理。而如果返回-1,則代表出錯。

阻塞式套接字最終發(fā)送返回的實際寫入字節(jié)數(shù)和請求字節(jié)數(shù)是相等的。發(fā)送成功僅僅表示的是數(shù)據(jù)被拷貝到了發(fā)送緩沖區(qū)中,并不意味著連接對端已經(jīng)收到所有的數(shù)據(jù)。至于什么時候發(fā)送到對端的接收緩沖區(qū),或者更進一步說,什么時候被對方應用程序緩沖所接收,對我們而言完全都是透明的。

總結

對于send發(fā)送數(shù)據(jù)來說,返回成功僅代表數(shù)據(jù)寫到發(fā)送緩存區(qū)成功,并不代表對端已經(jīng)接收成功。而對于read來說,需要循壞讀取數(shù)據(jù),并且要考慮EOF等異常條件。

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
關閉