UNP编程:22---套接字选项之(通用套接字选项:SOL_SOCKET)

  • 这些选项是协议无关的(也就是说,它们由内核中的协 议无关代码处理,而不是由诸如IPv4之类特殊的协议模块处理),不过其中有些选项只能应用到某些特定类型的套接字中。举例来说,尽管我们称SO_BROADCAST套接字选项是“通用”的,它 却只能应用于数据报套接字

一、SO_BROADCAST

  • 本选项开启或禁止进程发送广播消息的能力。只有数据报套接字支持广播,并且还必须是在支持广播消息的网络上(例如以太网、令牌环网等)。我们不可能在点对点链路上进行广播, 也不可能在基于连接的传输协议(例如TCP和SCTP)之上进行广播
  • 由于应用进程在发送广播数据报之前必须设置本套接字选项,因此它能够有效地防止一个 进程在其应用程序根本没有设计成可广播时就发送广播数据报。举例来说,一个UDP应用程序 可能以命令行参数的形式取得目的IP地址,不过它并不期望用户键入一个广播地址。处理方法 并非让应用进程来确定一个给定地址是否为广播地址,而是在内核中进行测试:如果该目的地 址是一个广播地址且本套接字选项没有设置,那么返回EACCES错误(TCPv2第233页)。

二、SO_DEBUG

  • 本选项仅由TCP支持。当给一个TCP套接字开启本选项时,内核将为TCP在该套接字发送和接收的所有分组保留详细跟踪信息。这些信息保存在内核的某个环形缓冲区中,并可使用trpt 程序进行检查
  • TCPv2第916~920页提供了更为详细的信息和使用了本选项的一个例子

三、SO_DONTROUTE

  • 本选项规定外出的分组将绕过底层协议的正常路由机制。举例来说,在IPv4情况下外出分组将被定向到适当的本地接口,也就是由其目的地址的网络和子网部分确定的本地接口。如果 这样的本地接口无法由目的地址确定(譬如说目的地主机不在一个点对点链路的另一端,也不 在一个共享的网络上),那么返回ENETUNREACH错误
  • 给函数send、sendto或sendmsg使用MSG_DONTROUTE标志也能在个别的数据报上取得与本选项相同的效果
  • 路由守护进程(routed和gated)经常使用本选项来绕过路由表(路由表不正确的情况下), 以强制将分组从特定接口送出

四、SO_ERROR

  • 当一个套接字上发生错误时,源自Berkeley的内核中的协议模块将该套接字的名为so_error的变量设为标准的Unix Exxx值中的一个,我们称它为该套接字的待处理错误(pending error)
  • 内核能够以下面两种方式之一立即通知进程这个错误:
    • ①如果进程阻塞在对该套接字的select调用上,那么无论是检查可读条件还是可 写条件,select均返回并设置其中一个或所有两个条件
    • ②如果进程使用信号驱动式I/O模型(第25章),那就给进程或进程组产生一个SIGIO信号。 进程然后可以通过访问SO_ERROR套接字选项获取so_error的值。由getsockopt返回的整 数值就是该套接字的待处理错误。so_error随后由内核复位为0(TCPv2第547页)
  • 当进程调用read且没有数据返回时,如果so_error为非0值,那么read返回-1且errno被 置为so_error的值(TCPv2第516页)。so_error随后被复位为0。如果该套接字上有数据在排 队等待读取,那么read返回那些数据而不是返回错误条件。如果在进程调用write时so_error 为非0值,那么write返回-1且errno被设为so_error的值(TCPv2第495页)。so_error随后被 复位为0

五、SO_KEEPALIVE

  • 待续

六、SO_LINGER

  • 待续

七、SO_OOBINLINE

  • 当本选项开启时,带外数据将被留在正常的输入队列中(即在线留存)。这种情况下接收函 数的MSG_OOB标志不能用来读带外数据。我们将在后面文章中详细讨论带外数据

八、SO_RCVBUF 和 SO_SNDBUF

九、SO_RCVLOWAT 和 SO_SNDLOWAT

  • 每个套接字还有一个接收低水位标记和一个发送低水位标记。它们由select函数使用。这两个套接字选项允许我们修改这两个低水位标记
    • 接收低水位标记是让select返回“可读”时套接字接收缓冲区中所需的数据量。对于TCP、 UDP和SCTP套接字,其默认值为1
    • 发送低水位标记是让select返回“可写”时套接字发送缓冲区中所需的可用空间。对于TCP套接字,其默认值通常为2048
  • 如select文章中所述,UDP也使用发送低水位标记,然而由于UDP套接字的发送缓冲区中可用空间的字节数从不改变(因为UDP并 不为由应用进程传递给它的数据报保留副本),只要一个UDP套接字的发送缓冲区大小大于该套 接字的低水位标记,该UDP套接字就总是可写。回顾UDP的缓冲区,我们记得UDP并没有发送缓冲区, 而只有发送缓冲区大小这个属性

十、SO_RCVTIMEO 和 SO_SNDTIMEO

  • 这两个选项允许我们给套接字的接收和发送设置一个超时值。注意,访问它们的 getsockopt和setsockopt函数的参数是指向timeval结构的指针,与select所用参数相同。这可让我们用秒数和微秒数来规定超时。我们通过设置其值为0s和0µs来禁止超时。默认 情况下这两个超时都是禁止的
  • 接收超时影响5个输入函数:read、readv、recv、recvfrom和recvmsg。发送超时影响5个输出函数:write、writev、send、sendto和sendmsg。我们将在后面文章详细讨论套接字超时

十一、SO_REUSEADDR 和 SO_REUSEPORT

演示案例

  • 设置SO_REUSERADDR选项来强制使用被处于TIME_WAIT状态的连接占用的socket地址,经过设置之后,即使sock处于TIME_WAIT状态,与之绑定的socket地址也可以立即被重用
  • 我们也可以通过修改内核参数/proc/sys/net/ipv4/cp_tw_recycle来快速回收被关闭的socket,从而使得TCP连接根本就不进入IME_WAIT状态,进而允许应用程序立即重用本地的socket地址
int sock=socket(AF_INET,SOCK_STREAM,0);
assert(sock);
int reuse=1;
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse));

struct sockaddr_in address;
......
......
int ret=bind(sock,(sruct sockaddr*)&address,sizeof(address));

十二、SO_TYPE

  • 本选项返回套接字的类型
  • 返回的整数值是一个诸如SOCK_STREAM或SOCK_DGRAM之类的值。本选项通常由启动时继承了套接字的进程使用。

十三、SO_USELOOPBACK

  • 本选项仅用于路由域(AF_ROUTE)的套接字。对于这些套接字,它的默认设置为打开(这 是唯一一个默认值为打开而不是关闭的SO_xxx二元套接字选项)。当本选项开启时,相应套接字 将接收在其上发送的任何数据报的一个副本
  • 禁止这些环回副本的另一个方法是调用shutdown,并设置它的第二个参数为SHUT_RD
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董哥的黑板报

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值