有多种方法设置和得到socket options
- getsockopt和setsockopt
- fcntl
- ioctl
#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
IP-layer socket options
transport-layer socket options
不支持错误为ENOPROTOOPT
Generic Socket Options
SO_BROADCAST
是否可以发送broadcast messages。
只有datagram sockets支持broadcast,不是所有网络硬件支持broadcast(如point-to-point link)。
SO_DEBUG
只有TCP支持,可通过trpt进行调试
SO_DONTROUTE
不使用路由机制。也可以send, sendto, sendmsg并设置MSG_DONTROUTE来达到效果。
经常被routing daemons使用。
如:对IPv4,包直接发送到设定好的本地接口,如果目标地址没有发现,ENETUNREACH返回
SO_ERROR
错误发生时,设置so_error。有两种方式,进程可得知error发生:
- 进程调用select阻塞时,返回
- 进程调用signal-driven I/O,SIGIO产生
通过getsockopt读取SO_ERROR socket option,可得到so_error,之后,so_error被设为0
如果so_error非0,当进程通过read并且没有数据返回,read返回-1,errno设置为so_error的值,so_error被设为0。当有数据时,返回这些数据。
如果so_error非0,当进程调用write,返回-1,errno设置为so_error的值,so_error被设为0。
SO_KEEPALIVE
当TCP keep-alive option被设置,2小时内没有数据交换,将自动发送一个keep-alive probe。
- peer回应一个ACK,正常,2小时后再来一次
- peer回应一个RST,说明对方重启了,设置ECONNRESET,socket关闭
- 无回应,重试一段时间后放弃。设置ETIMEDOUT,socket关闭。如果收到ICMP error,设置EHOSTUNREACH,socket关闭
SO_LINGER
struct linger {
int l_onoff; /* 0=off, nonzero=on */
int l_linger; /* linger time, POSIX specifies units as seconds */
};
- l_onoff为0,关闭。
- l_onoff不为0,l_linger为0,当关闭时终止连接,TCP舍弃在send buffer中的所有数据,并发送RST给对方,避免了TIME_WAIT状态。而不是平常的4次握手。
- l_onoff不为0,l_linger不为0,关闭时linger。当send buffer中有数据,进程睡眠直到数据发送完或linger时间到达。如socket设为nonblocking,不会等待。当使用SO_LINGER时,检查close的返回值比较重要,如果linger时间到了数据还没发完,返回EWOULDBLOCK并且所有没有发的数据都丢弃。
SO_OOBINLINE
out-of-band数据放入normal input queue
SO_RCVBUF SO_SNDBUF
设置buffer的大小,client要在connect前面,serve要在listen之前调用。
最小为MSS的4倍。
SO_RCVLOWAT and SO_SNDLOWAT
最低水位
SO_RCVTIMEO and SO_SNDTIMEO
超时
SO_REUSEADDR and SO_REUSEPORT