套接字機制提供兩個套接字選項接口來控制套接字的行為。一個接口用來設置選項,另一個接口允許查詢一個選項的狀態。可以獲取或設置的三種選項:
(1)通用選項,工作在所有套接字類型上。
(2)在套接字層次管理的選項,但是依賴于下層協議的支持。
(3)特定與某協議的選項,為每個協議所獨有。
Single UNIX Specification僅定義了套接字層的選項(上述三種選項中的前兩種選項)。
可以采用setsockopt函數來設置套接字選項。
#include <sys/socket.h>int setsockopt(int sockfd, int level, in option, const void *val, socklen_t len);返回值:若成功則返回0,出錯則返回-1
參數level標識了選項(option)應用的協議。如果選項(option)是通用的套接字層選項,level設置成SOL_SOCKET。否則,level設置成控制這個選項的協議號。例如,對于TCP選項,這是IPPROTO_TCP,對于IP選項,這是IPPROTO_IP。表16-10總結了Single UNIX Specification所定義的通用套接字層的選項。
表16-10 套接字選項
參數val根據選項(option)的不同指向一個數據結構或一個整數。一些選項是on/off開關。如果整數非零,那么選項(option)被啟用。如果整數為零,那么選項(option)被禁止。參數len指定了val指向的對象的大小。
可以使用getsockopt函數來發現選項的當前值。
#include <sys/socket.h>int getsockopt(int sockfd, int level, int option, void *restrict val, socklen_t *restrict lenp);返回值:若成功則返回0,出錯則返回-1
注意參數lenp是一個指向整數的指針。在調用getsockopt之前,設置該整數為復制選項緩沖區的大小。如果實際的尺寸大于此值,選項會被截斷而不報錯;如果實際尺寸正好等于或者小于此值,那么返回時將此值更新為實際尺寸。
實例
當服務器終止并嘗試立即重啟時,程序清單16-3中的函數不會正常工作。除非超時(這通常約為幾分鐘),通常TCP的實現不允許綁定同一個地址。幸運的是套接字選項SO_REUSEADDR允許越過這個限制,如程序清單16-9所示。
#include "apue.h"#include <errno.h>#include <sys/socket.h>int initserver(int type, const struct sockaddr *addr, socklen_t alen, int qlen){ int fd, err; int reuse = 1; if((fd = socket(addr->sa_family, type, 0)) < 0) return(-1); if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)) < 0) { err = errno; goto errout; } if(bind(fd, addr, alen) < 0) { err = errno; goto errout; } if(type == SOCK_STREAM || type == SOCK_SEQPACKET) { if(listen(fd, qlen) < 0) { err = errno; goto errout; } } return(fd);errout: close(fd); errno = err; return(-1);}
為了啟用SO_REUSEADDR選項,在setsockopt中val的參數設置為一個非零整數的地址。設置len參數為val所指的對象的大小。
本篇博文內容摘自《UNIX環境高級編程》(第二版),僅作個人學習記錄所用。關于本書可參考:http://www.apuebook.com/。
新聞熱點
疑難解答