套介面選項(轉)
套介面選項(轉)[@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
- 使用點陣圖選單項——點陣圖選單項例項 (轉)
- ls命令選項詳解(轉)
- IT避孕套 (轉)
- 選擇下拉選單項實現跳轉效果
- 軟體介面中選單的美化 (轉)
- SAP MM MIGO介面裡的'Via Delivery'選項Go
- FreeBSD其他核心設定選項(轉)
- FreeBSD 預設核心配置選項(轉)
- grep的-A-B-選項詳解(轉)
- MYSQL典型的configure選項(轉)MySql
- 組策略安全選項對應登錄檔項彙總(轉)
- 點選連結不跳轉例項程式碼
- 【轉】gcc中的-w -W和-Wall選項GC
- exp匯出命令中的query選項(轉)
- find命令的exec選項用法詳解(轉)
- 中文RFC文件遠端COM選項(一) (轉)
- 中文RFC文件遠端COM選項(二) (轉)
- 中文RFC文件遠端COM選項(三) (轉)
- 中文RFC文件遠端COM選項(四) (轉)
- Configure 引數選項詳解(轉)
- 影響mysqld安全的幾個選項(轉)MySql
- 核心編譯選單中相關選項的意義(轉)編譯
- 蘋果Lightning介面未來將提供更多功能選項蘋果
- 值得收藏的TCP套介面程式設計文章TCP程式設計
- 觀察下面的選項,選出正確的選項。
- java介面例項Java
- 動態生成select選項全接觸 (轉)
- cmdr 03 - 用流式介面定義命令列引數處理選項命令列
- tcp 選項TCP
- mysqldump 選項MySql
- 根據什麼選擇一套適合自己的linux系統?(轉)Linux
- 使用點陣圖選單項——新增線和圖形到選單 (轉)
- 使用點陣圖選單項——建立點陣圖 (轉)
- iOS 點選推送訊息跳轉指定介面 —總結篇iOS
- Win10網路介面卡沒有wifi選項怎麼辦?Win10系統電腦網路介面卡沒有wifi選項的解決方法Win10WiFi
- ABB機器人套介面通訊 機器人部分機器人
- 50套精美的免費PSD網頁介面素材網頁