UNIX网络编程读书笔记:套接口选项

红心概述

有不少方法来获取和设置影响套接口的选项:编程

  • getsockopt和setsockopt函数
  • fcntl函数
  • ioctl函数

红心getsockopt和setsockopt函数

这两个函数仅用于套接口。服务器

#include <sys/socket.h>
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t *optlen);
返回值:0——成功,-1——出错

其中,网络

sockfd必须指向一个打开的套接口描述字;socket

level(级别)指定系统中解释选项的代码:或为通用套接口代码,或为某个特定于协议的代码(例如IPv四、IPv六、TCP或SCTP)。函数

optval是一个指向变量(*optval)的指针,setsockopt从*optval中取得选项待设置的新值,getsockopt则把已获取的选项当前值存放到*optval中。spa

optlen指定*optval的大小,它对于setsockopt是一个值参数,对于getsockopt是一个值-结果参数。指针

套接口选项粗分为两大基本类型:code

(1)标志选项:开启或禁止某个特性的二元选项。blog

(2)值选项:取得并返回咱们能够设置或检查的特定值的选项。继承

*optval的值为0表示禁止选项,不为0表示开启选项。

红心fcntl函数

fcntl函数提供了与网络编程相关的以下特性:

  1. 非阻塞I/O。经过使用F_SETFL命令设置O_NONBLOCK文件状态标志,咱们能够把一个套接口设置为非阻塞型。
  2. 信号驱动I/O。经过使用F_SETFL命令设置O_ASYNC文件状态标志,咱们能够把一个套接口设置成一旦其状态发生变化,内核就产生一个SIGIO信号。
  3. F_SETOWN命令容许咱们指定用于接收SIGIO和SIGURG信号的套接口属主(进程ID或进程组ID)。其中SIGIO信号是套接口被设置为信号驱动I/O型后产生的,SIGURG信号是在新的带外数据到达套接口时产生的。F_GETOWN命令返回套接口的当前属主。
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* int arg */);
返回值:依赖于cmd参数——成功,-1——出错

每种描述字(包括套接口描述字)都有一组由F_GETFL命令获取或由F_SETFL命令设置的文件标志。其中影响套接口描述字的两个标志是:

O_NONBLOCK   非阻塞I/O

O_ASYNC         信号驱动I/O

灯泡注意灯泡

设置某个文件状态标志的惟一正确的方法是:先取得当前标志,与新标志逻辑或后再设置标志。例如,使用fcntl开启非阻塞I/O的典型代码是:

int flags;

if( (flags = fcntl(fd, F_GETFL, 0)) < 0)
    err_sys("F_GETFL error");
flags |= O_NONBLOCK;
if(fcntl(fd, F_SETFL, flags) < 0)
    err_sys("F_SETFL error");

红心信号SIGIO和SIGURG的独特之处

信号SIGIO和SIGURG与其余信号的不一样之处在于,这两个信号仅在已使用F_SETOWN命令给相关套接口指派了属主后才会产生。

F_SETOWN命令的整数类型arg参数既能够是一个正整数,指出接收信号的进程ID,也能够是一个负整数,其绝对值指出接收信号的进程组ID。

F_GETOWN命令把套接口属主做为fcntl函数的返回值返回,它既能够是进程ID(一个正的返回值),也能够是进程组ID(一个除-1之外的负值)。

指定接收信号的套接口属主为一个进程或一个进程组的差异在于:前者仅致使单个进程接收信号,然后者则致使整个进程组中的全部进程(也许不止一个进程)接收信号。

使用socket函数新建立的套接口并无属主。然而若是一个新的套接口是从一个监听套接口建立来的,那么套接口属主将由已链接套接口从监听套接口继承而来。

红心经常使用的套接口选项

灯泡SO_KEEPALIVE

给一个TCP套接口设置保持存活(keep-alive)选项后,若是2小时内在该套接口的任一方向上都没有数据交换,TCP就自动给对端发送一个保持存活探测分节(keep-alive probe)。这是一个对端必须响应的分节。

本选项的目的是检测对端主机是否崩溃或变得不可达。

本选项通常由服务器使用,不过客户也可使用。

服务器使用本选项是由于它们花大部分时间阻塞在等待穿越TCP链接的输入上,也就是说在等待客户的请求。然而若是客户主机链接掉线、电源掉电或系统崩溃,服务器进程将永远不会知道,并将继续等待永远不会到达的输入。咱们称这种状况为半开链接(half-open connection)。保持存活选项将检测出这些半开链接并终止它们。

灯泡SO_RCVBUF、SO_SNDBUF

每一个TCP套接口和SCTP套接口都有一个发送缓冲区和一个接收缓冲区,每一个UDP套接口都有一个接收缓冲区。SO_SNDBUF和SO_RCVBUF套接口选项容许咱们改变这些缓冲区的大小。对于客户,SO_RCVBUF选项必须在调用connect以前设置;对于服务器,SO_RCVBUF选项必须在调用listen以前给监听套接口设置。

灯泡SO_REUSEADDR

SO_REUSEADDR套接口选项为如下四个不一样的目的提供服务:

(1)SO_REUSEADDR容许启动一个监听服务器并捆绑其众所周知端口,即便之前创建的将该端口用做它们的本地端口的链接仍存在。

(2)SO_REUSEADDR容许在同一端口上启动对同一服务器的多个实例,只要每一个实例捆绑一个不一样的本地IP地址便可。

(3)SO_REUSEADDR容许单个进程捆绑同一端口到多个套接字上,只要每次捆绑指定不一样的本地IP地址便可。

(4)SO_REUSEADDR容许彻底重复的绑定:当一个IP地址和端口已绑定到某个套接口上时,若是传输协议支持,一样的IP地址和端口能够捆绑到另外一个套接口上。通常来讲,本特性只支持UDP套接口。

全部TCP服务器都应指定SO_REUSEADDR选项。

相关文章
相关标签/搜索