概述
我们可以通过若干个方法来修改套接字的选项,包括getsockopt和setsockopt函数,fcntl函数可以用于将套接字设置为非阻塞套接字或者信号驱动套接字以及修改套接字属主的方法
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
int getsockopt(int sockfd, int level, int optname, void * optval, socklen_t * optlen);
sockfd必须是一个已经打开的套接字,level指定系统中解释选项的代码或者为通用,或者为特定于协议,optval在set中会作为传入值,在get中作为传出值,optlen在set中是传入值,在get中是值-结果参数
套接字的状态
有些时候,一些套接字选项的设置需要考虑到时序,比方说keep_alive什么
因此有一些套接字选项会继承自监听套接字(否则在连接完成到accept过程都没有设置)
包括有SO_DEBUG, SO_DONTROUTE, SO_KEEPALIVE, SO_LINGER, SO_OOBINLINE, SO_RCVBUF, SO_RCVLOWAT, SO_SNDBUF, SO_SNDLOWAT
对于这些选项,我们只需要配置在监听套接字上就可以
通用套接字
SO_BROADCAST套接字选项
只适用于UDP,用于配置是否禁止还是开启广播消息的能力,在udp发布广播数据报之前必须配置该选项
SO_DEBUG套接字选项
仅支持TCP,设置之后,TCP会在所有的发送、接收分组上保留详细跟踪信息,被保存在内核的某个环形缓冲区中,可以使用trpt程序检查
SO_DONTROUTE套接字选项
规定绕过正常的路由机制。也就是说设置之后,将绕过路由表中网关的表项,在send,sendmsg,sendto中设置MSG_DONTROUTE有同样的效果
SO_ERROR套接字选项
该套接字不能配置只能通过SO_ERROR获取
如果套接字发生了错误,内核就会配置该套接字选项so_error为标准的Unix Exxx,而这会立刻通知到正在阻塞的select调用以及配置了信号驱动的套接字(会发送SIGIO信号)
read系统调用如果没有读到任何数据且SO_ERROR不为0,则会返回-1,errno设置为so_error配置值,之后so_error复位为0,如果so_error不为0但是有数据,那么会返回数据
write被调用的时候如果so_error不为0,那么返回-1,errno设置为so_error配置值,之后so_error复位为0
SO_KEEPALIVE套接字选项
设置SO_KEEPALIVE之后,如果两个小时套接字任意方向都没有数据交换,那么会发送一个存活确认分组,对此我们可能有四种结果,当然如果你仔细分析,你会发现这四个结果跟正常一个请求发送得到的