51-套接字选项(概述)

相信你学过前面的 TCP 协议也知道,里头的算法非常多,有些算法你可以开启,有些你可以关闭。比如你可以设置发送和接收缓冲区大小,也可以设置是否打开 Nagle 算法等等。这些是如何做到的呢?

有很多方法可以用来获取和设置影响套接字的选项:

  • getsockopt 和 setsockopt 函数
  • fcntl 函数
  • ioctl 函数

大多数情况,我们都使用 getsockopt 和 setsockopt 函数。

1. 套接字选项

getsockopt 和 setsockopt 函数是根据套接字的类别对其进行设置的,比如有些套接字选项和协议无关,这种就称为通用套接字选项。有些套接字选项和 TCP 协议相关,那么这种套接字选项就称为 TCP 套接字选项,比如用来打开和关闭 Nagle 算法的选项 TCP_NODELAY。

因为套接字选项的分类比较多,语言描述起来实在是太麻烦,我们用图 1 的思维导图可以一目了然。


这里写图片描述
图1 套接字选项的分类

有一些像 ipv6、sctp 这种类型的套接字,我们就不关心了,所以图 1 中只显示了一些我们比较关心的部分。毕竟套接字选项实在太多,有限的时间内根本不可能一个一个搞清楚,只有我们在用到的时候,再深入去研究它。

在后面的学习中,我会挑选几个常用的选项作为代表详细说明,比如通用套接字选项中的 SO_REUSEADDRSO_LINGER 等等。其它的等到以后我们知识足够用的时候再讲解。

2. setsockopt 和 getsockopt

这两个函数分别是对套接字设置和获取选项的值。函数原型如下:

#include <sys/types.h>          /* See NOTES */
#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);

参数 level 表示套接字选项的级别(类别),比如你如果要设置通用套接字选项,那么 level 就应该设置为 SOL_SOCKET,如果你要设置 TCP 套接字选项,level 就是 IPPROTO_TCP,具体可以参考图 1.

参数 optname 就是具体的选项名称了,比如你要设置 SO_REUSEADDR,你可以这样:

int reuse = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));

3. 套接字选项的数据类型

不同的套接字选项数据类型都不一样,但是主要包含以下两种:

  • bool 类型:主要用来打开和关闭某项功能,比如 TCP_NODELAY.
  • 带有具体数值的类型:
    • int : 主要用来设置某个参数的值,比如 SO_SNDBUF,它的类型就是缓冲区大小,是一个整型
    • 结构体:有些套接字的参数值可能不是单纯的整数类型,可是结构体,比如 SO_LINGER,它的数据类型是 struct linger.

setsockopt 和 getsockopt 函数的第 4 个参数是一个 void* 类型,正因为套接字选项的数据类型多种多样,所以这个参数就是一个 void* 类型了,它可以接收任何类型的指针,但是同时,你还得告诉第 5 个参数这个数据类型的大小。

这么多选项的数据类型,你也记不住,图 1 中每个选项后面的小括号中都标记了选项的数据类型,可以方便查看。

4. 实例

再举两个小例子

  • 比如我们要设置 SO_LINGER,那应该这样:
int ret, len;
struct linger lgr;
lgr.l_onoff = 1;
lgr.l_linger = 10;

// 设置 linger 的值
ret = setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &lgr, sizeof(lgr));
if (ret < 0) {
  perror("setsockopt");
}

// 获取 linger 的值
len = sizeof(lgr);
ret = getsockopt(sockfd, SOL_SOCKET, SO_LINGER, &lgr, &len);
if (ret < 0) {
  perror("getsockopt");
}
  • 打开 TCP_NODELAY 选项
int onoff = 1; // c 语言中不提供 bool 类型,因此只能使用 int 来替代。
setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &onoff, sizeof(onoff));

5. 总结

  • 知道套接字选项有哪些类别
  • 掌握 setsockopt 函数和 getsockopt 函数
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值