1. 套接字选项函数原型:
#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);
ret-成功返回0 失败返回-1
2. 通用套接字选项:
(1) SO_BROADCAST:
本选项开启或禁止进程发送广播消息的能力;只有数据报套接字支持广播,并且还必须是在支持广播消息的网络上;
(2) SO_DEBUG:
本选项仅由TCP支持。当给一个TCP套接字开启本选项,内核将为TCP在该套接字和接收的所有分组保留详细跟踪信息。这些信息保存在内核的某个环形缓冲区中,并可以使用trpt程序进行检查;
(3) SO_DONTROUTE:
本选项规定外出的分组将绕过底层协议的正常路由机制,以强制将分组从特定接口送出;
(4) SO_ERROR:
当一个套接字上发生错误时,源自Berkeley的内核中的协议模块将该套接字的名为so_error的变量设为标准的Unix_Exxx值中的一个,我们称它为该套接字的待处理错误。内核能够以下面的两种方式之一立即通知进程这个错误;
--如果进程阻塞在对该套接字的select调用上,那么无论是检查可读条件还是可写条件,select均返回并设置其中一个或所有两个条件;
--如果进程使用信号驱动式I/O模型,那就给进程或者进程产生一个SIGIO信号;
进程然后可以通过访问SO_ERROR套接字选项后去so_error值。由getsockopt返回的整数值就是该套接字的待处理错误。so_error随后由内核复位为0;
(5) SO_KEEPALIVE:
给一个tcp套接字设置保持存活选项后,如果2小时内在该套接字的任一方向上没有数据交换,tcp就自动给对端发送一个保持存活探测分节。这是一个对端必须响应的tcp分节,它会导致以下三种情况之一;
--对端以期望的ack响应。应用进程得不到通知。在又经过无动静的2小时之后,tcp将发出另外一个探测分节;
--对端以rst响应,它告知本端tcp,对端已崩溃且重新启动。该套接字的待处理错误被置ECONNRESET,套接字本身则被关闭;
--对端对保持存活探测分节没有任何响应。源自Berkeley的tcp将另外发送8个探测分节,两两相隔75秒,视图得到一个响应。如果探测分节没有响应,该套接字的处理错误被置为ETIMEOUT;
(6) SO_LINGER:
--shutdown, SHUT_RD: 在套接字上不能再发出接收请求,进程仍可以网套接字发送时数据,套接字接收缓冲区中所有数据被丢弃;再接收到任何的tcp丢弃;对套接字发送缓冲区没有任何影响;
--shutdown, SHUT_WR: 在套接字上不能再发出发送请求,进程仍可以从套接字接收数据,套接字发送缓冲区中的内容被发送到对端,后跟正常的tcp连接终止序列,即发送fin,对套接字接收缓冲区没有任何影响;
--close,l_onoff=0: 在套接字上不能再发出发送或者接收请求;套接字发送缓冲区中的内容被发送到对端,如果描述符引用计数变为0,在发送完发送缓冲区中的数据后,跟以正常的tcp连接终止序列,套接字接收缓冲区中的内容被丢弃;
--close,l_onoff = 1, l_linger = 0: 在套接字上不能再发出发送或接收请求;如果描述符引用计数变为0,rst被发送到对端;连接状态被置为CLOSED(没有TIME_WAIT);套接字发送缓冲区和套接字接收缓冲区中的数据被丢弃;
--close, l_onoff = 1, l_linger != 0: 在套接字上不能再发出发送或者接收请求;套接字发送缓冲区的数据被发送到对端;如果描述符引用计数为0,在发送完缓冲区中的数据后,跟以正常的tcp连接终止序列;套接字接收缓冲区的数据被丢弃;如果在连接变为CLOSED状态前延滞时间到,那么colose返回EWOULDBLOCK错误;
(7) SO_RCVBUF, SO_SNDBUF:
每个套接字都有一个发送缓冲区和一个接收缓冲区;TCP套接字的缓冲区大小至少应该是MSS的4倍;MSS=MTU-40头部,一般以太网卡MTU是1500;典型缓冲区默认大小是8192字节或者更大;对于一次发送大量数据,可以增加到48K,64K等;为了达到最佳性能,缓冲区可能至少要与BDP(带宽延迟乘积)一样大小;对于接收大量数据的,提高接收缓冲区能够减少发送端的阻塞;
TCP设置这个两个选项注意顺序:对于客户端必须在调用connect之前,对于服务器端应该在调用listen之前,因为窗口选项是在建立连接时用syn分节与对端互换得到的;
(8) SO_RCVLOWAT, SO_SNDLOWAT:
每个套接字还有一个接收低水位标记和一个发送低水位标记。他们由select函数使用,接收低水位标记是让select返回可读时套接字接收缓冲区中所需的数据量;对于tcp,udp,默认值是1;发送低水位标记是让select返回可写时套接字发送缓冲区中所需的可用空间;对于tcp套接字,其默认值通常为2048;
(9) SO_RCVTIMEO, SO_SNDTIMEO:
这两个选项允许我们给套接字的接收和发送设置一个超时值,注意,访问getsockopt和setsockopt函数的参数是指向timeval的指针,与select所用的参数相同;
(10) SO_TYPE:
本选项返回套接字的类型,返回的整数值是一个注入SOCK_STREAM或者SOCK_DGRAM之类的值;本选项通常由启动时继承了套接字的进程使用;
(11) SO_USELOOPBACK:
本选项仅用于路由域(AF_ROUTE)套接字,默认设置是打开,相应套接字 将接收在其上发送的任何数据报的一个副本;
(12) SO_REUSEADDR:
TCP先调用close()的一方会进入TIME_WAIT状态,只有设置了SO_REUSEADDR选项的socket,才可以重复绑定使用。server程序总是应该在调用bind之前设置SO_REUSEADDR套接字选项。
这个套接字选项通知内核,如果端口忙,但TCP状态位于 TIME_WAIT ,可以重用端口。如果端口忙,而TCP状态位于其他状态,重用端口时依旧得到一个错误信息,指明"地址已经使用中"。如果你的服务程序停止后想立即重启,而新套接字依旧使用同一端口,此时SO_REUSEADDR 选项非常有用。必须意识到,此时任何非期望数据到达,都可能导致服务程序反应混乱,不过这只是一种可能,事实上很不可能。
3. tcp套接字选项:
(1) TCP_MAXSEG:
本选项允许我们获取或者设置TCP连接的最大分节大小(MSS)。已建立连接返回的是对端使用syn通知的MSS值,否则是未从对端收到MSS情况下使用的默认值;
(2) TCP_NODELAY:
开启本选项将禁止TCP的Nagle算法,默认情况下Nagle算法是启动的;关于Nagle算法,单独总结一篇;