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 函数

说明:本文转自blog.csdn.net,用于学习交流分享,仅代表原文作者观点。如有疑问,请联系我们删除~