getsockopt()
是 Linux 网络编程中用于获取套接字选项信息的系统调用。您提供的代码片段:
::getsockopt(sockfd_, SOL_TCP, TCP_INFO, tcpi, &len)
用于获取 TCP 连接的底层状态信息。以下是详细解释和注意事项:
1. 参数解析
参数 | 类型 | 作用 |
---|---|---|
sockfd_ | int | TCP 套接字的文件描述符 |
SOL_TCP | int | 选项层级,表示操作 TCP 协议层 |
TCP_INFO | int | 选项名称,表示获取 TCP 连接详细信息 |
tcpi | struct tcp_info* | 指向存储结果的结构体指针(需预先分配内存) |
&len | socklen_t* | 输入时为 tcpi 缓冲区大小;输出时为实际写入的数据长度 |
2. 关键数据结构
struct tcp_info
包含 TCP 连接的核心指标(需包含头文件 <netinet/tcp.h>
):
struct tcp_info {
uint8_t tcpi_state; // TCP 状态(如 ESTABLISHED, TIME_WAIT)
uint32_t tcpi_ca_state; // 拥塞控制状态
uint32_t tcpi_rto; // 超时重传时间(微秒)
uint32_t tcpi_rtt; // 平滑往返时间(微秒)
uint32_t tcpi_snd_mss; // 发送方最大报文段大小
// ... 其他字段(不同内核版本有差异)
};
3. 使用示例
#include <sys/socket.h>
#include <netinet/tcp.h> // 包含 TCP_INFO
int sockfd_ = ...; // 已建立的 TCP 套接字
struct tcp_info tcpi; // 存储结果的结构体
socklen_t len = sizeof(tcpi); // 初始化缓冲区大小
// 获取 TCP 信息
if (::getsockopt(sockfd_, SOL_TCP, TCP_INFO, &tcpi, &len) == 0) {
printf("TCP State: %u\n", tcpi.tcpi_state);
printf("RTT: %u μs\n", tcpi.tcpi_rtt);
} else {
perror("getsockopt(TCP_INFO) failed");
}
4. 常见用途
- 监控连接状态:检测连接是否存活(
tcpi_state == TCP_ESTABLISHED
) - 性能分析:获取 RTT(往返时间)、拥塞窗口大小等
- 故障诊断:检查丢包率、重传超时时间
- 拥塞控制:读取当前拥塞算法状态(如 BBR、CUBIC)
5. 注意事项
- 权限要求:进程需有
CAP_NET_ADMIN
能力(或 root 权限) - 内核兼容性:
struct tcp_info
字段随内核版本变化(需验证字段可用性) - 错误处理:
- 返回
-1
表示失败(可通过errno
获取错误码) - 常见错误:
EBADF
(无效套接字)、ENOPROTOOPT
(不支持选项)
- 返回
- 实时性:数据为瞬时快照,需周期性调用以跟踪变化
⚠️ 建议通过
man 7 tcp
和man getsockopt
查阅当前系统的完整文档。