套接字选项
套接字机制有两种套接字选项接口来控制套接字行为:一种接口用来设置选项;另一种接口允许查询一个选项的状态;可以设置或获取下面三种选项:
- 通用选项,工作在所有套接字类型上;
- 在套接字层次管理的选项,但依赖于下层协议的支持;
- 特定于某种协议的选项,为每个协议所独有;
若要对套接字选项进行设置时,可以调用函数 setsockopt 进行设置,调用函数 getsockopt 获取套接字选项的当前值,其定义如下:
/* 套接字选项 */
/*
* 函数功能:设置套接字选项;
* 返回值:若成功返回0,若出错返回-1;
* 函数原型:
*/
#include <sys/socket.h>
int setsockopt(int sockfd, int level, int option, const void *val, socklen_t len);
/*
* 说明:
* level表示选项应用的协议,若选项是通用套接字选项,则level设置为SOL_SOCKET,否则设置为控制这个协议的协议号;
* val根据选项 option 不同指向一个数据结构或者一个整数,若整数非零,则启用选项,若整数为零,则禁止选项;
* len指定了val指向的对象的大小;
*/
/*
* 函数功能:获取套接字选项的当前值;
* 返回值:若成功返回0,若出错返回-1;
* 函数原型:
*/
#include <sys/socket.h>
int getsockopt(int sockfd, int level, int option, void *val, socklen_t *lenp);
/*
* 说明:
* lenp是指向整数的指针,在调用该函数之前,设置该参数为复制选项缓冲区的大小;
* 其他参数和setsockopt函数类型;
*/
下面是通用套接字选项取值:
带外数据
带外数据是一些通信协议所支持的可选特征,允许更高优先级的数据比普通数据优先传输。即使传输队列已经有数据,带外数据先行传输。TCP 支持带外数据,但是 UDP 并不支持。
TCP 将带外数据称为紧急数据,但是 紧急数据 并不是 带外数据。TCP 仅支持一个字节的紧急数据,但是允许紧急数据在普通数据传输机制数据流之外传输。为了产生紧急数据,在三个 send 函数中任何一个指定标志 MSG_OOB。如果带 MSG_OOB 标志传输字节超过一个时,最后一个字节被看做紧急数据字节。
TCP 支持紧急标记:在普通数据流中紧急数据所在的位置,如果采用套接字选项 SO_OOBINLINE,那么可以在普通数据中接收紧急数据。判断是否接收到紧急标记,可以使用函数 sockatmark,其定义如下:
/*
* 函数功能:判断是否接收到紧急标记;
* 返回值:若在标记处则返回0,若没有在标记处则返回0,若出错返回-1;
* 函数原型:
*/
#include <sys/socket.h>
int sockatmark(int sockfd);
/*
* 说明:
* 当下一个要读的字节在紧急标记所标识的位置,则该函数返回1;
*/
当带外数据出现在套接字读取队列时,select函数会返回一个文件描述符,并且拥有一个异常状态挂起。可以在普通数据流上接收紧急数据,或者在某个recv函数中采用MSG_OOB 标志在其他队列数据之前接收紧急数据。TCP 队列仅有一个字节的紧急数据,如果在接收当前的紧急数据字节之前又有新的紧急数据到来,那么当前的字节会被丢弃。