套接字选项

套接字选项

一、相关方法

1、getsockopt 和 setsockopt 函数

#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

2、fcntl 函数

#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);         
int fcntl(int fd, int cmd, struct flock *lock);

典型的设置socket阻塞、非阻塞的案例

if((flags = fcntl(fd, F_GETFL, 0)) < 0)
	err_sys("F_GETFL error");
flags |= O_NONBLOCK; //设置为非阻塞
// flags &= ~O_NONBLOCK; //设置为阻塞
if(fcntl(fd, F_SETFL, flags) < 0)
	err_sys("F_SETFL error");

iotcl函数

二、选择说明 level值、optname值

level值一般有:SOL_SOCKET,IPPROTO_IP,IPPROTO_ICMPV6,IPPROTO_IPV6,IPPROTO_TCP,IPPROTO_SCTP。重点关注:SOL_SOCKET,IPPROTO_IP,IPPROTO_TCP

1、SOL_SOCKET

通用的套接字选项

选项名说明数据类型
SO_BROADCAST允许发送广播数据int
SO_DEBUG允许调试int
SO_DONTROUTE不查找路由int
SO_ERROR获得套接字错误int
SO_KEEPALIVE保持连接int
SO_LINGER延迟关闭连接struct linger
SO_OOBINLINE带外数据放入正常数据流int
SO_RCVBUF接收缓冲区大小int
SO_SNDBUF发送缓冲区大小int
SO_RCVLOWAT接收缓冲区下限int
SO_SNDLOWAT发送缓冲区下限int
SO_RCVTIMEO接收超时struct timeval
SO_SNDTIMEO发送超时struct timeval
SO_REUSERADDR允许重用本地地址和端口int
SO_TYPE获得套接字类型int
SO_BSDCOMPAT与BSD系统兼容int

重点选项说明:
(1) SO_DONTROUTE
设置该选项要求源和目的主机在同一网络或端对端可达,即不经过路由。

(2) SO_KEEPALIVE
主要是为服务端主机起作用,为未关闭的TCP连接提供2小时一次的心跳检测。主要针对客户端主机崩溃或者不可达(即主机都来不及发出最后一个FIN结束信号),这种情况下如果套接字未设置SO_KEEPALIVE,则服务端一直监听并占用socket,浪费资源。

(3) SO_LINGER
设置socket调用close() 关闭套接字的时,距离真正关闭套接字的逗留时间。缺省的close()行为:如果有数据残留在socket发送缓冲区中,则系统将继续发送这些数据给对方,等待被确认,然后发送FIN关闭套接字。
SO_LINGER选项用来改变此缺省设置。使用如下结构:

struct linger {
     int l_onoff; /* 0 = off, nozero = on */
     int l_linger; /* linger time */
};

有下列三种情况:

  1. 设置 l_onoff 为0,则该选项关闭,l_linger 的值被忽略,等于内核缺省情况,close调用会立即返回给调用者,如果可能将会传输任何未发送的数据;
  2. 设置 l_onoff 为非0,l_linger 为0,则套接口关闭时TCP夭折连接,TCP将丢弃保留在套接口发送缓冲区中的任何数据并发送一个RST给对方,而不是通常的四分组终止序列,这避免了TIME_WAIT状态;
  3. 设置 l_onoff 为非0,l_linger为非0,当套接口关闭时内核将拖延一段时间(由l_linger决定)。如果套接口缓冲区中仍残留数据,进程将处于睡眠状态,直 到(a)所有数据发送完且被对方确认,之后进行正常的终止序列(描述字访问计数为0)或(b)延迟时间到。此种情况下,应用程序检查close的返回值是非常重要的,如果在数据发送完并被确认前时间到,close将返回EWOULDBLOCK错误且套接口发送缓冲区中的任何数据都丢失。close的成功返回仅告诉我们发送的数据(和FIN)已由对方TCP确认,它并不能告诉我们对方应用进程是否已读了数据。如果套接口设为非阻塞的,它将不等待close完成。

(4) SO_REUSERADDR
允许两种情况下绑定“相同”的IP:PORT对,

  1. 地址通配符 ‘0.0.0.0’ 与任一具体的本地地址 不相冲突;
  2. 处于TIME_WAIT状态的IP:PORT对,可以被再次成功绑定

SO_REUSEPORT 允许将任意数目的socket绑定到完全相同的 IP:PORT 对上,前提条件是所有绑定这个IP:PORT 对的socket都设置了SO_REUSEPORT选项。另外绑定了相同IP:PORT对的socket必须去connect不同的远端IP:PORT,否则会得到EADDRINUSE错误。

2、IPPROTO_IP

针对ip协议的套接字选项

选项名说明数据类型
IP_HDRINCL在数据包中包含IP首部int
IP_OPTINOSIP首部选项int
IP_RECVDSTADDR返回目的IP地址int
IP_RECVIF返回接收接口索引int
IP_TOS服务类型int
IP_TTL生存时间int

3、IPPROTO_TCP

针对tcp协议的套接字选项

选项名说明数据类型
TCP_MAXSEGTCP最大数据段的大小int
TCP_NODELAY不使用Nagle算法int

Nagle算法的基本定义是任意时刻,最多只能有一个未被确认的小段. 所谓“小段”,指的是小于MSS尺寸的数据块,所谓“未被确认”,是指一个数据块发送出去后,没有收到对方发送的ACK确认该数据已收到.
Nagle算法的规则(可参考tcp_output.c文件里tcp_nagle_check函数注释):
(1)如果包长度达到MSS,则允许发送;
(2)如果该包含有FIN,则允许发送;
(3)设置了TCP_NODELAY选项,则允许发送;
(4)未设置TCP_CORK选项时,若所有发出去的小数据包(包长度小于MSS)均被确认,则允许发送;
(5)上述条件都未满足,但发生了超时(一般为200ms),则立即发送.

默认情况下,发送数据采用Nagle算法.这样虽然提高了网络吞吐量,但是实时性却降低了,在一些交互性很强的应用程序来说是不允许的,使用TCP_NODELAY选项可以禁止Nagle 算法.此时,应用程序向内核递交的每个数据包都会立即发送出去.需要注意的是,虽然禁止了Nagle 算法,但网络的传输仍然受到TCP确认延迟机制的影响.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值