9.1 套接字的多种可选项
2025/11/29大约 3 分钟
9.1 套接字的多种可选项
可配置的选项
| 协议层 | 选项名 | 说明 | R/W |
|---|---|---|---|
| SOL_SOCKET socket相关设置 来源 `socket.h` | SO_DEBUG | Record debugging information. | |
| SO_ACCEPTCONN | Accept connections on socket. | ||
| SO_REUSEADDR | Allow reuse of local addresses. | ||
| SO_KEEPALIVE | Keep connections alive and send SIGPIPE when they die. | ||
| SO_SNDBUF | Send buffer size. | ||
| SO_RCVBUF | Receive buffer size. | ||
| SO_TYPE | Compatible name for SO_STYLE. | R | |
| IPPROTO_IP ip协议相关设置。来源 `in.h` | IP_TOS | int; IP type of service and precedence. | |
| IP_TTL | int; IP type of service and precedence. | ||
| IP_MULTICAST_IF | in_addr; set/get IP multicast i/f | ||
| IP_MULTICAST_TTL | unsigned char; set/get IP multicast ttl | ||
| IP_MULTICAST_LOOP | bool; set/get IP multicast loopback | ||
| IPPROTO_TCP TCP 协议相关设置 来源 `tcp.h` | TCP_NODELAY | Turn off Nagle's algorithm. | |
| TCP_MAXSEG | Limit MSS | ||
| TCP_KEEPINTVL | Interval between keepalives |
注:未说明R/W 的均为可读可写选项
get
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int getsockopt(int sockfd, int level, int optname,
void *optval, socklen_t *optlen);| 参数 | 值 | 用途 | 说明 |
|---|---|---|---|
| sockfd | socket file descriptor | ||
| level | SOL_SOCKET、IPPROTO_IP、IPPROTO_TCP | 可配置选项按照协议分类,对于socket单独用SOL_SOCKET。 | |
| optname | SO_TYPE、IP_TTL | 指定要配置的选项的名称 | |
| optval | identify a buffer in which the value for the requested option(s) are to be returned | ||
| optlen | a value-result argument, initially containing the size of the buffer pointed to by optval, and modified on return to indicate the actual size of the value returned. |
int tcp_sock, upd_sock;
int sock_type;
socklen_t optlen;
tcp_sock = socket(PF_INET, SOCK_STREAM, 0);
upd_sock = socket(PF_INET, SOCK_DGRAM, 0);
printf("SOCK_STREAM: %d\n", SOCK_STREAM);
printf("SOCK_DGRAM: %d\n", SOCK_DGRAM);
int state;
state = getsockopt(tcp_sock, SOL_SOCKET, SO_TYPE, &sock_type, &optlen);
if(state == -1)
unix_error("getsockopt error for TCP socket");
else
printf("TCP socket type: %d\n", sock_type);效果:
SOCK_STREAM: 1
SOCK_DGRAM: 2
TCP socket type: 1
UDP socket type: 2set
读写SO_SNBUF
实现:
int sock = socket(PF_INET, SOCK_STREAM, 0);
socklen_t buf_size;
socklen_t optlen = sizeof(buf_size);
int state;
state = getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &buf_size, &optlen);
if(state == -1)
unix_error("getsockopt error for TCP socket");
else
printf("TCP sock sendbuffer size : %d\n", buf_size);
buf_size = 0;
state = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &buf_size, optlen);
//...| 行号 | 功能 | 说明 |
|---|---|---|
| 13 | 设置sendbuffer 的大小为0 | setsockopt 最后一个参数的类型是 socklen_t optlen,指示设置的参数的内存大小 |
效果:
TCP sock sendbuffer size : 16384
TCP sock sendbuffer size changed to : 4608设置过后重新通过get获取sendbuffer 的大小,返回的结果和设置的值-0 不一致。
相关信息
通过调用setsockopt 向系统传递我们的请求。要实现流控制和错误发生时的重传机制,至少要有一些缓冲空间。
一些选项只能告知系统有请求,具体是否采用,采用的值由系统根据协议决定。
这里虽然sendbuffer 的值虽然设置为0,但比初始设置的buffer 大小 16384 也减少了很多(可能是个最小值)
| 设置值 | 实际值 |
|---|---|
| 5000 | 10000 |
| 4609 | 9218 |
| 4607 | 9214 |
| 1000 | 4608 |
问:为什么实际值是设置值的两倍?而不是按照设置值来(非4608情况下)