Linux Socket Programming by Example-第十二章 设置socket参数

这一章的难点是理解每个参数的物理意义。

一边问google一边问百度,感觉有些理解了,但又有些模糊。

真是纸上得来终觉浅,绝知此事要躬行。


不管怎么样,先简单了解下。


接口:

#include <sys/types.h>

#include <sys/socket.h>

int getsockopt(int s,

    int level,

    int optname,

    const void* optval,

   socklen_t *optlen);


int setsockopt(int s,

    int level,

    int optname,

    const void* optval,

   socklen_t optlen);


Level     与  Option Name

SOL_SOCKET SO_REUSEADDR

SOL_SOCKET SO_KEEPALIVE

SOL_SOCKET SO_LINGER

SOL_SOCKET SO_BROADCAST

SOL_SOCKET SO_OOBINLINE

SOL_SOCKET SO_SNDBUF

SOL_SOCKET SO_RCVBUF

SOL_SOCKET SO_TYPE

SOL_SOCKET SO_ERROR

SOL_TCP       SO_NODELAY


详细解释:

SO_SNDBUF    控制发送端缓冲区大小。

SO_RCVBUF   控制接收端缓冲区大小

注意:

1> 设置值必须满足一个 最大值与最小值, 本地写代码测试后发现是[256, 4* 1024* 1024]

查看文档,发现最大值是下面2个内核参数控制:

/proc/sys/net/core/rmem_max   r:read 接收端

/proc/sys/net/core/wmem_max   w:write 发送端

进一步可以执行:获取3个值  最小值 默认值  最大值

cat /proc/sys/net/ipv4/tcp_wmem

cat /proc/sys/net/ipv4/tcp_rmem

UDP的话,是下面3个: (意思还不是很明确)

cat /proc/sys/net/ipv4/udp_mem

cat /proc/sys/net/ipv4/udp_rmem_min

cat /proc/sys/net/ipv4/udp_wmem_min

2> 在这个区间内,获取值为设置值的2倍。即调用set(10000)后,get返回值为20000.


核心问题:

多大合适?客户端、服务器端?UDP还是TCP?网络规模?并发连接数?

要回答这个问题,可能还是需要在实际项目中做性能测试才能回答。


SO_TYPE  获取socket类型
查看内核代码,可知道其枚举定义如下:
enum sock_type {
SOCK_STREAM = 1,
SOCK_DGRAM = 2,
SOCK_RAW = 3,
SOCK_RDM = 4,
SOCK_SEQPACKET= 5,
SOCK_DCCP = 6,
SOCK_PACKET = 10,
};


SO_REUSEADDR


解决SOCKET的复用问题。
问题:
回到前面11章,Server端调用fork启动子进程,子进程会继续使用同一个socket与client端连接。
如果Server端崩溃后再启动,调用listen函数来监听同一个socket(IP,Port),系统会返回EADDRINUSE。
为了解决这个问题,Server端在调用listen函数之前,必须设置SO_REUSEADDR为TRUE。


注意:该选项只对TCP有效。


SO_LINGER
查了下字典,linger在英语中是徘徊的意思。
设置这个选项后,调用close时,系统会阻塞一段时间(由SO_LINGER设置),再返回。


设置参数:
struct linger {
int l_onoff; //开关选项
int l_linger; //等待时间,以秒为单位
};


这个选项我的感觉并不是太好,一遇到Timeout,便引发了驱动编程里面的经典问题:
Timeout到底设置为多大? 理论依据有吗?
其实,很多情况下都是一个经验值。这个值可靠吗?大多数情况下都是天知道。

通常应该设置为>=2 MSL (不过遗憾的是MSL是动态变化的。)


SO_KEEPALIVE


这个选项的物理意义就是系统每2个小时定时发送探测消息(probe)。
条件:2小时内双方无数据交互
触发动作:给对方发送探测消息
反馈消息处理:
状态1:对方接收一切正常:以期望的ACK响应。
状态2:对方已崩溃且已重新启动:以RST响应。套接口的待处理错误被置为ECONNRESET,套接 口本身则被关闭。
状态3:对方无任何响应:11分钟内系统会多次发送探测消息。如果大约11分钟内,无回应,则套接口的待处理错误被置为ETIMEOUT,套接口本身则被关闭。如ICMP错误是“host unreachable(主机不可达)”,说明对方主机并没有崩溃,但是不可达,这种情况下待处理错误被置为 EHOSTUNREACH。


相关参数:
/proc/sys/net/ipv4/tcp_keepalive_time  默认值75s
/proc/sys/net/ipv4/tcp_keepalive_probes 默认值9   (9*75 = 大约11分钟15秒)
/proc/sys/net/ipv4/tcp_keepalive_time  默认值7200 (2小时)


SO_BROADCAST
启动组播支持
主要:设置的socket必须支持组播,否则无效


SO_OOBINLINE
OOB是Out of band data的缩写,意思是该消息比较紧急,需要马上处理。
该选项的实际意义是在TCP流里引入了优先队列的概念。


SO_PASSCRED与SO_PEERCRED
只支持本地socket,CRED代表数字身份验证
阅读过Android代码的,可以发现Android在property机制中使用了该选项。


进一步查看linux内核可以发现,还有IP层等其他协议的option设置。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值