套介面選項(轉)
套介面選項(轉)[@more@]獲取和設定影響套介面選項的函式:getsockopt :獲取套介面選項 setsockopt: 獲取套介面選項 fcntl: 設定套介面為非阻塞I/O型訊號驅動I/O型等 oictl 套介面選項 SO-KEEPALIVE SO-LINGER SE-RCVBUF 和 SO-SNDBUF SO-RCVWAT和 SO-SNDLOWAT SO-RCVTIMEO和 SO-SNDTIMEO SO-REUSEADDR和 SO-REUSPORT IP-TTL TCP-KEEPALIVE--------------------------------------------------------------------------------getsockopt 和 setsockopt獲得套介面選項: int getsockopt ( int sockfd, int level, int optname, void * optval, socklen_t *opteln ) 設定套介面選項: int setsockopt ( int sockfd, int level, int optname, const void * optval, socklen_t *opteln ) sockfd(套接字): 指向一個開啟的套介面描述字 level:(級別): 指定選項程式碼的型別。 SOL_SOCKET: 基本套介面 IPPROTO_IP: IPv4套介面 IPPROTO_IPV6: IPv6套介面 IPPROTO_TCP: TCP套介面 optname(選項名): 選項名稱 optval(選項值): 是一個指向變數的指標 型別:整形,套介面結構,其他結構型別:linger{}, timeval{ } optlen(選項長度) :optval 的大小返回值:標誌開啟或關閉某個特徵的二進位制選項--------------------------------------------------------------------------------檢查套介面選項的程式輸出套介面的選項: 定義感興趣的套介面選項 呼叫getsockopt 輸出套介面選項 定義聯合:不同的套介面選項有不同型別union val { //套介面選項可能有的5個型別分別作為一個成員: int i_val; long l_val; char c_val[10]; struct linger linger_val; struct timeval timeval_val; //struct {int S; int uS} } val;//函式原型(prototype),這些函式用於輸出套介面選項的值 static char *sock_str_flag(union val *, int); //靜態函式,只可在本檔案中被呼叫 static char *sock_str_int(union val *, int); static char *sock_str_linger(union val *, int); static char *sock_str_timeval(union val *, int); //定義結構sock_opts, 其中包含了獲得或輸出套介面選項的所有資訊 struct sock_opts { char *opt_str; //字元名稱 int opt_level; //級別 int opt_name; //名稱 char *(*opt_val_str)(union val *, int); //函式指標,用於輸出, }//定義結構陣列並初始化 struct sock_opts sock_opts[ ] = { //全域性變數陣列才可以初始化 "SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, sock_str_flag, "SO_DEBUG", SOL_SOCKET, SO_DEBUG, sock_str_flag, #ifdef SO_REUSEPORT //編譯時用的宏定義 "SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, sock_str_flag, #else //沒有這個選項 "SO_REUSEPORT", 0, 0, NULL, //NULL表示沒有定義 #endif "SO_TYPE", SOL_SOCKET, SO_TYPE, sock_str_int, "IP_TTL", IPPROTO_IP, IP_TTL, sock_str_int, "TCP_MAXSEG", IPPROTO_TCP,TCP_MAXSEG, sock_str_int, NULL, { /*結束標誌 */} 0, 0, NULL }; 源程式: int main(int argc, char **argv) { int fd, len; struct sock_opts *ptr; //結構型別 fd = Socket(AF_INET, SOCK_STREAM, 0); //獲得套接字 for (ptr = sock_opts; ptr->opt_str != NULL; ptr++) { //從第一個選項到最後一個 printf(“%s: ”, ptr->opt_str); //輸出字元名 if (ptr->opt_val_str == NULL) //沒有定義的情況 printf("(undefined)
"); else { len = sizeof(val); //獲得套介面選項 if (getsockopt(fd, ptr->opt_level, ptr->opt_name, val, len) == -1) { //返回值為1,函式呼叫失敗 err_ret("getsockopt error");} //輸出選項的預設值 else printf("default = %s
", (*ptr->opt_val_str)(&val, len)); } } //End of for loop exit(0); }static char strres[128]; //靜態變數,在函式呼叫後保留原值 static char * sock_str_flag(union val *ptr, int len) { if (len != sizeof(int)) //長度不相符 snprintf(strres, sizeof(strres), "size (%d) not sizeof(int)", len); else //轉換字串 snprintf(strres, sizeof(strres),"%s", (ptr->i_val == 0) ? "off" : "on"); return(strres); }----------------------------------------------------------------------------------------------------------------------------------------------------------------基本套介面選項SO_KEEPALIVE檢測對方主機是否崩潰,避免(伺服器)永遠阻塞於TCP連線的輸入。 設定該選項後,如果2小時內在此套介面的任一方向都沒有資料交換,TCP就自動給對方 發一個保持存活探測分節(keepalive probe)。這是一個對方必須響應的TCP分節.它會導致以下三種情況: 對方接收一切正常:以期望的ACK響應。2小時後,TCP將發出另一個探測分節。對方已崩潰且已重新啟動:以RST響應。套介面的待處理錯誤被置為ECONNRESET,套接 口本身則被關閉。對方無任何響應:源自berkeley的TCP傳送另外8個探測分節,相隔75秒一個,試圖得到一個響應。在發出第一個探測分節11分鐘15秒後若仍無響應就放棄。套介面的待處理錯誤被置為ETIMEOUT,套介面本身則被關閉。如ICMP錯誤是“host unreachable(主機不可達)”,說明對方主機並沒有崩潰,但是不可達,這種情況下待處理錯誤被置為 EHOSTUNREACH。SO_RCVBUF和SO_SNDBUF每個套介面都有一個傳送緩衝區和一個接收緩衝區。 接收緩衝區被TCP和UDP用來將接收到的資料一直儲存到由應用程式來讀。 TCP:TCP通告另一端的視窗大小。 TCP套介面接收緩衝區不可能溢位,因為對方不允許發出超過所通告視窗大小的資料。這就是TCP的流量控制,如果對方無視視窗大小而發出了超過宙口大小的資料,則接 收方TCP將丟棄它。 UDP:當接收到的資料包裝不進套介面接收緩衝區時,此資料包就被丟棄。UDP是沒有流量控制的;快的傳送者可以很容易地就淹沒慢的接收者,導致接收方的UDP丟棄資料包。SO_LINGER 指定函式CLOSE對面相連線的協議如何操作——當由資料殘留在套介面傳送緩衝區時的處理 LINGER結構 struct linger { int l_onoff; // 0=off, nonzero=on int l_linger; //linger time in seconds };SO_RCVLOWAT 和SO_SNDLOWAT每個套介面都有一個接收低潮限度和一個傳送低潮限度。它們是函式selectt使用的,接收低潮限度是讓select返回“可讀”而在套介面接收緩衝區中必須有的資料總量。 ——對於一個TCP或UDP套介面,此值預設為1。傳送低潮限度是讓select返回“可寫” 而在套介面傳送緩衝區中必須有的可用空間。對於TCP套介面,此值常預設為2048。 對於UDP使用低潮限度,由於其傳送緩衝區中可用空間的位元組數是從不變化的,只要 UDP套介面傳送緩衝區大小大於套介面的低潮限度,這樣的UDP套介面就總是可寫的。 UDP沒有傳送緩衝區,只有傳送緩衝區的大小。--------------------------------------------------------------------------------TCP 套介面選項TCP_KEEPALIVE指定TCP開始傳送保持存活探測分節前以秒為單位的連線空閒時間。預設值至少必須為7200秒,即2小時。此選項僅在SO_KEPALIVEE套介面選項開啟時才有效。TCP_MAXSEG獲取或設定TCP連線的最大分節大小(MSS)。返回值是我們的TCP傳送給另一端的最大資料量,它常常就是由另一端用SYN分節通告的MSS,除非我們的TCP選擇使用一個比對方通告的MSS小些的值。如果此值在套介面連線之前取得,則返回值為未從另·—端收到Mss選項的情況下所用的預設值。小於此返回值的信可能真正用在連線上,因為譬如說使用時間戳選項的話,它在每個分節上佔用12位元組的TCP選項容量。我們的TcP將傳送的每個分節的最大資料量也可在連線存活期內改變,但前提是TCP要支援路徑MTU 發現功能。如果到對方的路徑改變了,此值可上下調整。--------------------------------------------------------------------------------例程式://獲得傳送緩衝區大小和MSS大小,設定傳送緩衝區大小//獲得傳送緩衝區大小和MSS大小 #include "unp.h" #include /* for TCP_MAXSEG */ int main(int argc, char **argv) { int sockfd, rcvbuf, mss; socklen_t len; struct sockaddr_in servaddr; if (argc != 2) err_quit("usage: rcvbuf "); sockfd = Socket(AF_INET, SOCK_STREAM, 0); len = sizeof(rcvbuf); Getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, rcvbuf, len); len = sizeof(mss); Getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len); printf("defaults: SO_RCVBUF = %d, MSS = %d
", rcvbuf, mss); bzero(servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(13); /* daytime server */ Inet_pton(AF_INET, argv[1], servaddr.sin_addr); Connect(sockfd, (SA *) &servaddr, sizeof(servaddr)); len = sizeof(rcvbuf); Getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len); len = sizeof(mss); Getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len); printf("after connect: SO_RCVBUF = %d, MSS = %d
", rcvbuf, mss); exit(0); }//設定傳送緩衝區大小 #include "unp.h" #include /* for TCP_MAXSEG value */ int main(int argc, char **argv) { int sockfd, mss, sendbuff; socklen_t optlen; float kk; sockfd = Socket(AF_INET, SOCK_STREAM, 0); /* Fetch and print the TCP maximum segment size. */ optlen = sizeof(mss); sendbuff =2048; Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, sendbuff, sizeof(sendbuff)); optlen = sizeof(sendbuff); Getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, sendbuff, &optlen); printf("After send buffer size = %d
", sendbuff); exit(0);
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8225414/viewspace-944698/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- UGUI_關卡選項介面UGUI
- SAP MM MIGO介面裡的'Via Delivery'選項Go
- 4881.152報告→過濾器逆轉, 13報告, 8快捷鍵,15首選項,5選項,T3選單欄過濾器
- 觀察下面的選項,選出正確的選項。
- cmdr 03 - 用流式介面定義命令列引數處理選項命令列
- iOS 點選推送訊息跳轉指定介面 —總結篇iOS
- 值得收藏的TCP套介面程式設計文章TCP程式設計
- JS 控制 兩個ListBox之間選擇移動項 (轉發)JS
- 157首選項→想法→隱藏標籤提示, 15首選項, 8快捷鍵,15首選項,5選項,T3選單欄,4919....
- Win10網路介面卡沒有wifi選項怎麼辦?Win10系統電腦網路介面卡沒有wifi選項的解決方法Win10WiFi
- 選項中選擇現在
- jquery選項卡jQuery
- ASP.NET Core - 選項系統之選項驗證ASP.NET
- 企業數字化轉型的必選項:整合自動化
- [轉帖]openEuler 22.03 LTS 核心基礎頁大小配置選項討論
- 【ionic】介面跳轉
- Tkinter (13) 選項選單部件 OptionMenu
- Swoole server配置選項Server
- 小程式 — 選項卡
- HTML <datalist> 選項列表HTML
- HTML datalist 選項列表HTML
- cppcheck指令常用選項
- javascript tab選項卡JavaScript
- 玩轉 PHP 網路程式設計全套之 socket 選項設定 APIPHP程式設計API
- 閒談IPv6-沒有選項勝有選項的TLV
- 純css tab選項卡程式碼例項CSS
- jQuery tab選項卡效果程式碼例項jQuery
- 轉賬介面設計
- gcc或g++的編譯選項 -shared -fPIC 與 -g -rdynamic 部分轉載GC編譯
- 手把手擼套框架-ORM框架的選擇框架ORM
- linux 中 sort -k選項Linux
- 管理 MySQL Shell 配置選項MySql
- PostgreSQL copy相關選項SQL
- QListWidget項新增勾選框
- EasyUi之Tabs(選項卡)UI
- golang中的選項模式Golang模式
- 4.5.1.3.1 語法和選項
- 4.5.1.1.1 語法和選項
- compare用法示例•選項摘要