今天一直在研究字选项之类的问题,现在正好有机会和大家分享一下.
================================================
套接字机制供给了两个套接字选项接口来制控套接字的为行。一个接口用来置设选项,另外一个接口用来答应我们求请选项的状态。我们可以获得以及置设三种型类的选项。
1.通用选项,可以任务在所有的套接字型类。
2.在套接字层次面上行进理管的选项,但是赖依底部协议的支撑。
3.和个每协议相干的协议选项。
Single UNIX Specification 只定义了套接字层的选项(面上所提到的后面两项)
我们可以通过setsockopt函数来置设套接字选项。
#include <sys/socket.h>
int setsockopt(int sockfd, int level, int option, const void *val, socklen_t len);
返回:如果胜利返回0,如果误错返回1。
参数level用来辨分option所应用的协议。如果option是通用套接字层次的选项,那么level置设成SOL_SOCKET。否则level置设成制控option的协议号。例如IPPROTO_TCP于用TCP选项,以及IPPROTO_IP于用IP选项。上面的表中就列出了Single UNIX Specification定义的通用的套接字层次的选项。
套接字选项
+-------------------------------------------------------------------------------------------------------------+
| Option | Type of val argument | Description |
|---------------+----------------------+----------------------------------------------------------------------|
| SO_ACCEPTCONN | int | 返回套接字否是激活于用侦听(只于用getsockopt)。 |
|---------------+----------------------+----------------------------------------------------------------------|
| SO_BROADCAST | int | 如果*val非0那么广播数据报。 |
|---------------+----------------------+----------------------------------------------------------------------|
| SO_DEBUG | int | 如果*val非0那么激活络网驱动的试调。 |
|---------------+----------------------+----------------------------------------------------------------------|
| SO_DONTROUTE | int | 如果*val非0,那么略忽平日的路由。 |
|---------------+----------------------+----------------------------------------------------------------------|
| SO_ERROR | int | 返回并且清除交提的套接字误错(只于用getsockopt)。 |
|---------------+----------------------+----------------------------------------------------------------------|
| SO_KEEPALIVE | int | 如果*val非0,那么激活期定活动的息消。 |
|---------------+----------------------+----------------------------------------------------------------------|
| SO_LINGER | struct linger | 如果有未发送的息消存在以及套接字关闭,那么做迟延。 |
|---------------+----------------------+----------------------------------------------------------------------|
| SO_OOBINLINE | int | 如果*val非0,那么将带外数据嵌入到常正数据中。 |
|---------------+----------------------+----------------------------------------------------------------------|
| SO_RCVBUF | int | 接收缓存的节字巨细。 |
|---------------+----------------------+----------------------------------------------------------------------|
| SO_RCVLOWAT | int | receive调用返回的最小数据节字。 |
|---------------+----------------------+----------------------------------------------------------------------|
| SO_RCVTIMEO | struct timeval | 套接字receive调用的超时值。 |
|---------------+----------------------+----------------------------------------------------------------------|
| SO_REUSEADDR | int | 如果*val非0,那么重复应用bind的地址。 |
|---------------+----------------------+----------------------------------------------------------------------|
| SO_SNDBUF | int | send缓存中的节字巨细。 |
|---------------+----------------------+----------------------------------------------------------------------|
| SO_SNDLOWAT | int | 一次send调用传输的最小数据节字量。 |
|---------------+----------------------+----------------------------------------------------------------------|
| SO_SNDTIMEO | struct timeval | 一个套接字send调用的超时值。 |
|---------------+----------------------+----------------------------------------------------------------------|
| SO_TYPE | int | 鉴别套接字型类(只在getsockopt中)。 |
+-------------------------------------------------------------------------------------------------------------+
参数val指向一个数据结构或者数整,这取决于option。有些选项是on/off开关。 如果这个数整非0,那么option被激活。如果这个数整是0,那么option不被激活。len参数指定val指向的对象的巨细。
我们可以通过函数getsockopt来取获前当option的值。
#include <sys/socket.h>
int getsockopt(int sockfd, int level, int option, void *restrict val, socklen_t *restrict lenp);
返回:如果胜利返回0,如果误错返回1。
意注lenp参数是一个指向数整的指针。在调用getsockopt之前,我们置设数整为option被拷贝的缓存的巨细,如果际实的option巨细比这个巨细大,那么option就会被截断。如果际实的option巨细比size小或者样同大,那么数整会在返回的时候被更新成际实的巨细。
例子
后面的(initserver)函数当服务进程终止的时候操纵失败,然后我们实验即立重新启动。一般来说,TCP的现实会会阻挠我们将样同一个地址绑定,除非超时。SO_REUSEADDR的套接字选项答应我们略忽这个制限,上面的代码就展示了这个性特。
为了激活SO_REUSEADDR选项,我们置设数整为一个非0的值然后将数整的地址做为val参数传递给setsockopt函数。我们置设len参数为一个示表数整的巨细,来示表val所指向的对象的巨细。
服务进程应用地址重用初始化一个将要被应用的套接字末了
#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); }
文章结束给大家分享下程序员的一些笑话语录: Google事件并不像国内主流媒体普遍误导的那样,它仅仅是中国Z府和美国公司、中国文化和美国文化甚至中国人和美国人之间的关系,是民族主义和帝国主义之间的关系;更重要的是,它就是Z府和公司之间的关系,是权力管制和市场自由之间的关系。从这个意义上说,过度管制下的受害者,主要是国内的企业。Google可以抽身而去,国内的企业只能祈望特区。www.ishuo.cn