日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

socket 选项 详细说明

發(fā)布時(shí)間:2025/3/15 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 socket 选项 详细说明 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

下面的兩個(gè)函數(shù)主要是用于設(shè)置socket文件描述符屬性的方法


getsockopt 和setsockopt這兩個(gè)函數(shù)成功時(shí)返回0,失敗時(shí)返回-1并設(shè)置errno ,可以使用 strerror(errno) 將錯(cuò)誤碼轉(zhuǎn)換為對(duì)應(yīng)的提示消息。

例子如下

/*查詢和設(shè)置接收緩沖區(qū)*/ int recvbuf = 0; int len = sizeof( recvbuf ); getsockopt( sock, SOL_SOCKET, SO_RCVBUF, &recvbuf, ( socklen_t* )&len); DC_INFO( "the receive buffer size before settting is %d", recvbuf );recvbuf = size; if(0 != setsockopt( sock, SOL_SOCKET, SO_RCVBUF, &recvbuf, sizeof( recvbuf) )) {DC_ERROR("setsockopt SO_RCVBUF error ,errmsg = %s",strerror(errno));return SERVER_ERROR; }

下面進(jìn)行一些詳細(xì)介紹

1.對(duì)于服務(wù)器而言,有部分socket選項(xiàng)只能在listen前針對(duì)監(jiān)聽socket設(shè)置才有效!這是因?yàn)檫B接socket只能由accept調(diào)用返回,而accept從listen監(jiān)聽隊(duì)列中接受的連接至少已經(jīng)完成了TCP三次握手的前兩個(gè)步驟(因?yàn)閘isten監(jiān)聽隊(duì)列中的連接至少已進(jìn)入SYN_RCVD狀態(tài)),這說明服務(wù)器已經(jīng)往被接收連接上發(fā)出了TCP同步報(bào)文段。但有的socket選項(xiàng)卻應(yīng)該在TCP同步報(bào)文段中設(shè)置,比如TCP最大報(bào)文選項(xiàng)!對(duì)應(yīng)的解決方案是:對(duì)監(jiān)聽socket設(shè)置這些socket選項(xiàng),那么accept返回的連接socket將自動(dòng)繼承這些選項(xiàng)!


? 這些選項(xiàng)包括SO_DEBUG,SO_DONTROUTE,SO_LINGER,SO_OOBINLINE,SO_RCVBUF,SO_RCVLOWAT,SO_SNDBUF,SO_SNDLOWAT,TCP_MAXSEG和TCP_NODELAY。而對(duì)于客戶端而言,這些socket必須在connect之前設(shè)置,因?yàn)閏onnect調(diào)用成功之后 tcp的三次握手已經(jīng)完成了!

2.SO_REUSEADDR選項(xiàng)

tcp服務(wù)器連接的TIME_WAIT狀態(tài),可以通過設(shè)置該選項(xiàng)是的綁定的socket地址立即被重用!


此外還有個(gè)另外的方式,修改內(nèi)核參數(shù) /proc/sys/net/ipv4/tcp_tw_recycle 來快速回收被關(guān)閉的socket ,從而使得tcp連接國(guó)標(biāo)不會(huì)進(jìn)入TIME_WAIT狀態(tài),進(jìn)而使得程序可以立即重用本地的socket地址!

3.SO_RCVBUF 和SO_SNDBUF

這兩個(gè)選項(xiàng)分別表示TCP接收緩沖區(qū)和發(fā)送緩沖區(qū)的大小!


不過當(dāng)我們通過setsockopt來設(shè)置tcp的接受和發(fā)送緩沖區(qū)大小的時(shí)候,系統(tǒng)會(huì)將其值加倍,并且不得小于某個(gè)最小值,同時(shí)也不得超過最大值!不過每個(gè)系統(tǒng)值可能有不同的默認(rèn)值!

此外我們還可以直接修改內(nèi)核參數(shù)?/proc/sys/net/ipv4/tcp_rmem 和/proc/sys/net/ipv4/tcp_wmem 來強(qiáng)制修改tcp接收和發(fā)送緩沖區(qū)的限制!

代碼如下

int SocketServer::make_socket_buffsize(int sock,int size) {/*查詢和設(shè)置接收緩沖區(qū)*/int recvbuf = 0;int len = sizeof( recvbuf );getsockopt( sock, SOL_SOCKET, SO_RCVBUF, &recvbuf, ( socklen_t* )&len);DC_INFO( "the receive buffer size before settting is %d", recvbuf );recvbuf = size;if(0 != setsockopt( sock, SOL_SOCKET, SO_RCVBUF, &recvbuf, sizeof( recvbuf) )){DC_ERROR("setsockopt SO_RCVBUF error ,errmsg = %s",strerror(errno));return SERVER_ERROR;}getsockopt( sock, SOL_SOCKET, SO_RCVBUF, &recvbuf, ( socklen_t* )&len);DC_INFO( "the receive buffer size after settting is %d", recvbuf );/*查詢和設(shè)置發(fā)送緩沖區(qū)*/int sendbuf = 0;getsockopt( sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, ( socklen_t* )&len);DC_INFO( "the tcp send buffer size before setting is %d", sendbuf );sendbuf = size;if(0 != setsockopt( sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, sizeof( sendbuf) )){DC_ERROR("setsockopt SO_SNDBUF error ,errmsg = %s",strerror(errno));return SERVER_ERROR;}getsockopt( sock, SOL_SOCKET, SO_SNDBUF, &sendbuf, ( socklen_t* )&len);DC_INFO( "the tcp send buffer size after setting is %d", sendbuf );return SERVER_OK; }

設(shè)置之后的最大值一般就是默認(rèn)一次可以讀取的字節(jié)數(shù)!

4.SO_RCVLOWAT 和SO_SNDLOWAT 選項(xiàng)

這兩個(gè)選項(xiàng)分別表示tcp接受和發(fā)送緩沖區(qū)的低水位標(biāo)志。它們一般被I/O復(fù)用系統(tǒng)調(diào)用來判斷socket是否可讀或可寫。

當(dāng)tcp接收緩沖區(qū)中可讀數(shù)據(jù)的總數(shù)大于低水位標(biāo)記時(shí),I/O系統(tǒng)調(diào)用將通知應(yīng)用程序可以從對(duì)于的socket讀取數(shù)據(jù),當(dāng)TCP發(fā)送緩沖區(qū)中的空閑空間大于其低水位,將通知應(yīng)用程序可以往對(duì)應(yīng)的socket上寫數(shù)據(jù)。

默認(rèn)情況下,這兩個(gè)選項(xiàng)均為1字節(jié)!

5.SO_LINGER?

此選項(xiàng)指定函數(shù)close對(duì)面向連接的協(xié)議如何操作(如TCP)。內(nèi)核缺省close操作是立即返回,如果有數(shù)據(jù)殘留在套接口緩沖區(qū)中則系統(tǒng)將試著將這些數(shù)據(jù)發(fā)送給對(duì)方。

struct linger {int l_onoff; /* 0 = off, nozero = on */int l_linger; /* linger time */ };有下列三種情況:
1、設(shè)置 l_onoff為0,則該選項(xiàng)關(guān)閉,l_linger的值被忽略,等于內(nèi)核缺省情況,close調(diào)用會(huì)立即返回給調(diào)用者,如果可能將會(huì)傳輸任何未發(fā)送的數(shù)據(jù);
2、設(shè)置 l_onoff為非0,l_linger為0,close系統(tǒng)調(diào)用立即返回,TCP將丟棄保留在套接口發(fā)送緩沖區(qū)中的任何數(shù)據(jù)并發(fā)送一個(gè)RST給對(duì)方。
3、設(shè)置 l_onoff 為非0,l_linger為非0,此時(shí)的close的行為取決兩個(gè)條件:一是被關(guān)閉的socket對(duì)應(yīng)的TCP發(fā)送緩沖區(qū)是否還有殘留的數(shù)據(jù);二是該socket是阻塞的還是非阻塞的。對(duì)于阻塞的socket,close將等到l_linge的時(shí)間,直到tcp模塊發(fā)送完所有殘留數(shù)據(jù)并得到對(duì)方的確認(rèn)。如果這段時(shí)間tcp沒有發(fā)送完殘留的數(shù)據(jù),那么close將返回-1,并將errno設(shè)置為EWOULDBLOCK。如果該socket是非阻塞的,close將立即返回,此時(shí)我們需要根據(jù)返回值和errno來判斷殘留數(shù)據(jù)是否已經(jīng)發(fā)送完畢!

總結(jié)

以上是生活随笔為你收集整理的socket 选项 详细说明的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。