7 套接字选项

#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);


通用套接字选项:

1、SO_BROADCAST

允许和禁止进程发送广播消息的能力,广播仅能用于UDP。如果UDP进程用一个广播地址作为目的地址,但是该选项为开启,那么返回EACCES错误,是不会发送广播消息的。


2、SO_KEEPALIVE

允许套接字每隔2小时发送探测分节,这个分节对端必须给予响应。本端发送探测分节,会遇到如下3种情况:

  1. 正常情况,对端发送ack响应,这种情况对于应用层是透明的,应用层是没有感知的;
  2. 对端崩溃并已经重启,对端响应RST,待处理错误被设置为ECONNRESET,套接字关闭;
  3. 对端掉电或崩溃或网络不可达,对端无响应,本端超时重传8个分节,超时则设置ETIMEOUT,收到ICMP错误消息,则设置EHOSTUNREACH。

对于本选项常见问题是修改发送周期2小时,需要修改内核,但是要注意的是,如果内核被修改,则这台机器上的所有套接字,均采用此周期时间。

本选项对于探测对端是否崩溃,是否掉线非常有效,如果对端已经出现问题,本端则处于半连接的状态,浪费系统资源。


3、SO_LINGER

struct linger {
    int l_onoff;   // 0=off nonzero=on
    int l_linger;  // linger time(second)
}

  1. 如果为未设置SO_LINGER,默认操作是close直接返回,但是如果发送缓冲区有数据会尝试将数据发送给对端
  2. 如果l_onoff为非零,l_linger为零,close中止该TCP连接,丢弃发送缓冲区数据,并发送RST消息给对端
  3. 如果l_onoff为非零,l_linger为非零,如果发送缓冲区有数据,2种情况close返回,1)则将等待l_linger时间后,超时,close返回,2)当然如果l_linger时间之前数据已经发送完毕(注意,这个发送完毕,确切说是收到对端的ack,数据确认),close返回。如果等待l_linger时间后发送缓冲区种还有数据(确切说未收到对端的数据确认ack消息)则close返回EWOULDBLOCK错误。
close具体返回时机看下面3个图:


总结:设置了l_linger,close成功返回,先前发送的数据和FIN消息,已由对端TCP确认,而不是应用层已经成功读取数据。不过通过对l_linger和shutdown的讨论,不禁要想,对于一般的网络应用,确认对端是否已经收到消息,并不是非常重要,所以一般的close就可以满足要求。同时设置l_onoff=1,l_linger=0,有特殊应用,如果探测网络已经有问题,比如应用层发现发送超时或其它异常,则直接丢弃发送和接收缓冲区数据,RST到对端,连接终止非常干净。

4、SO_RCVBUF SO_SNDBUF
对于接收缓冲区的设置必须在listen和accept之前。


TCP套接字选项

1、TCP_NODELAY

开启本选项,是为了禁止TCP的Nagle算法,该算法目的是为了减少网络上小分节数据的数量,它会将多个小分节数据合并到一个分节进行发送,以减少网络负载,同时Nagle算法常常和ACK延滞算法放到一起执行,也就是说不单独发送ACK消息,而是当有数据发送时,由当前数据捎带过去。


从这个图中可以看出,如果服务器发送小字节,并且需要客户端已最快的速度回响应ack,则需要禁止Nagle算法,通常采用TCP_NODELAY选项则是一个好选择

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值