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 | |
| SO_ERROR | Get and clear the pending socket error. | 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(7) | TCP_NODELAY | Turn off Nagle's algorithm. | |
| TCP_MAXSEG | Limit MSS | ||
| TCP_KEEPINTVL | Interval between keepalives | ||
| TCP_USER_TIMEOUT | How long for loss retry before timeout | it specifies the maximum amount of time in milliseconds that transmitted data may remain unacknowledged, or buffered data may remain untransmitted (due to zero window size) before TCP will forcibly close the corresponding connection and return ETIMEDOUT to the application. 已经发送的包仍未被确认-未收到对应的ACK(发送数据后启动计时) 或 缓冲区内的数据仍未发送-对方缓冲已满(处于zero window size 启动计时)的最大时间。超时后连接被forcibly 关闭,返回错误码为ETIMEOUT |
注:未说明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情况下)