套接字选项

本文详细介绍了TCP套接字的各种选项,包括SO_BROADCAST、SO_ERROR、SO_KEEPALIVE等,讨论了它们的作用和应用场景,如检测对端主机状态、设置缓冲区大小、超时值和禁用Nagle算法等,帮助理解TCP连接管理和优化。
摘要由CSDN通过智能技术生成
#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);
  • 对于TCP已连接套接字,下面的套接字选项须从监听套接字继承得到:
    SO_DEBUGSO_DONTROUTESO_KEEPALIVESO_LINGERSO_OOBINLINESO_RCVBUFSO_RCVLOWATSO_SNDBUFSO_SNDLOWATTCP_MAXSEGTCP_NODELAY

SO_BROADCAST

本选项开启或禁止进程发送广播消息的能力。只有数据报套接字支持广播,并且还必须是在支持广播消息的网络上(例如以太网、令牌环网等)。如果目的地址是一个广播地址且本套接字选项没有设置,那么返回EACCES错误。

SO_ERROR

这是个可以获取但不能设置的套接字选项。当一个套接字上发生错误时,源自Berkeley的内核中的协议模块将该套接字的名为so_error的变量设为标准的Unix Exxx值中的一个(pending error,待处理错误),内核可以通过”SIGIO信号“或者”select调用“立即通知进程这个错误,然后进程可以通过SO_ERROR套接字选项获取so_error的值。

SO_KEEPALIVE

本选项的功用是检测对端主机是否崩溃或变得不可达。我们必须明白内核通过socket的read/write将双方的连接异常通知到应用层的能力是有限的。假如A机器上的一个进程a正在和B机器上的进程b通信,当B机器的OS崩溃/主机断电/网络不可达时,a进程不会收到FIN包作为连接终止的提示。此时对于a进程有如下情况:

-如果a进程阻塞在read上,那么结果只能是永远的等待。
-如果a进程先write然后阻塞在read,由于收不到B机器TCP/IP栈的ack,TCP会持续重传,然后在阻塞的read调用上返回错误:
ETIMEDOUT/EHOSTUNREACH/ENETUNREACH。假如B机器恰好在某个时候恢复和A机器的通路,并收到a某个重传的pack,
因为不能识别所以会返回一个RST,此时a进程上阻塞的read调用会返回错误ECONNREST。

因此,socket对这些错误还是有一定的反馈能力的,前提是在对面不可达时你依然做了一次write调用,而不是轮询或是阻塞在read上,那么总是会在重传的周期内检测出错误。如果没有那次write调用,应用层永远不会收到连接错误的通知。

给一个TCP套接字设置存活SO_KEEPALIVE选项后,如果2小时内(大多数内核基于整个内核维护该时间参数,而不是基于套接字的)在该套接字的任一方向上都没有数据交换,TCP就自动给对端发送一个保持存活探测分节(keep-alive probe)

SO_RCVBUF和SO_SNDBUF

每个套接字都有一个发送缓冲区和一个接收缓冲区,这两个套接字选项允许我们改变这两个缓冲区的默认大小。对于TCP来说,套接字接收缓冲区不可能溢出,因为不允许对端发出超过本端所通告窗口大小的数据,这就是TCP的流量控制。对于UDP来说,由于没有流量控制,较快的发送端可以很容易地淹没较慢的接收端,导致接收端的UDP丢弃数据报。

当设置TCP套接字接收缓冲区的大小时,函数调用顺序很重要,这是因为TCP的窗口规模选项是在建立连接时用SYN分节与对端互换得到的。
对于客户,这意味着SO_RCVBUF选项必须在调用connect之前设置;
对于服务器,这意味着SO_RCVBUF选项必须在调用listen之前给监听套接字设置。

SO_RCVLOWAT和SO_SNDLOWAT

每个套接字还有一个接收低水位标记和一个发送低水位标记,它们由select函数使用。这两个套接字选项允许我们修改这两个低水位标记。

-接收低水位标记是让select返回“可读”时套接字接收缓冲区中所需的数据量。对于TCP和UDP,其默认值为1。
-发送低水位标记是让select返回“可写”时套接字发送缓冲区中所需的可用空间。对于TCP,其默认值为
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值