套接字機(jī)制提供兩個(gè)套接字選項(xiàng)接口來控制套接字的行為。一個(gè)接口用來設(shè)置選項(xiàng),另一個(gè)接口允許查詢一個(gè)選項(xiàng)的狀態(tài)。可以獲取或設(shè)置的三種選項(xiàng):
(1)通用選項(xiàng),工作在所有套接字類型上。
(2)在套接字層次管理的選項(xiàng),但是依賴于下層協(xié)議的支持。
(3)特定與某協(xié)議的選項(xiàng),為每個(gè)協(xié)議所獨(dú)有。
Single UNIX Specification僅定義了套接字層的選項(xiàng)(上述三種選項(xiàng)中的前兩種選項(xiàng))。
可以采用setsockopt函數(shù)來設(shè)置套接字選項(xiàng)。
#include <sys/socket.h>int setsockopt(int sockfd, int level, in option, const void *val, socklen_t len);返回值:若成功則返回0,出錯(cuò)則返回-1
參數(shù)level標(biāo)識(shí)了選項(xiàng)(option)應(yīng)用的協(xié)議。如果選項(xiàng)(option)是通用的套接字層選項(xiàng),level設(shè)置成SOL_SOCKET。否則,level設(shè)置成控制這個(gè)選項(xiàng)的協(xié)議號(hào)。例如,對于TCP選項(xiàng),這是IPPROTO_TCP,對于IP選項(xiàng),這是IPPROTO_IP。表16-10總結(jié)了Single UNIX Specification所定義的通用套接字層的選項(xiàng)。
表16-10 套接字選項(xiàng)
參數(shù)val根據(jù)選項(xiàng)(option)的不同指向一個(gè)數(shù)據(jù)結(jié)構(gòu)或一個(gè)整數(shù)。一些選項(xiàng)是on/off開關(guān)。如果整數(shù)非零,那么選項(xiàng)(option)被啟用。如果整數(shù)為零,那么選項(xiàng)(option)被禁止。參數(shù)len指定了val指向的對象的大小。
可以使用getsockopt函數(shù)來發(fā)現(xiàn)選項(xiàng)的當(dāng)前值。
#include <sys/socket.h>int getsockopt(int sockfd, int level, int option, void *restrict val, socklen_t *restrict lenp);返回值:若成功則返回0,出錯(cuò)則返回-1
注意參數(shù)lenp是一個(gè)指向整數(shù)的指針。在調(diào)用getsockopt之前,設(shè)置該整數(shù)為復(fù)制選項(xiàng)緩沖區(qū)的大小。如果實(shí)際的尺寸大于此值,選項(xiàng)會(huì)被截?cái)喽粓?bào)錯(cuò);如果實(shí)際尺寸正好等于或者小于此值,那么返回時(shí)將此值更新為實(shí)際尺寸。
實(shí)例
當(dāng)服務(wù)器終止并嘗試立即重啟時(shí),程序清單16-3中的函數(shù)不會(huì)正常工作。除非超時(shí)(這通常約為幾分鐘),通常TCP的實(shí)現(xiàn)不允許綁定同一個(gè)地址。幸運(yùn)的是套接字選項(xiàng)SO_REUSEADDR允許越過這個(gè)限制,如程序清單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選項(xiàng),在setsockopt中val的參數(shù)設(shè)置為一個(gè)非零整數(shù)的地址。設(shè)置len參數(shù)為val所指的對象的大小。
本篇博文內(nèi)容摘自《UNIX環(huán)境高級(jí)編程》(第二版),僅作個(gè)人學(xué)習(xí)記錄所用。關(guān)于本書可參考:http://www.apuebook.com/。
新聞熱點(diǎn)
疑難解答
圖片精選