核心 API
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);
int ioctl(int fd, int request, ...);
level:協議層級(SOL_SOCKET、IPPROTO_IP、IPPROTO_TCP)。
optname:具體選項名稱。
optval:指向選項值的緩衝區(輸入/輸出)。
SOL_SOCKET 通用選項
| 選項 | 類型 | 說明 |
| SO_REUSEADDR | int | 允許 bind 到 TIME_WAIT 狀態的埠,伺服器快速重啟必備 |
| SO_KEEPALIVE | int | 啟用 TCP 保活機制(預設 2 小時無數據才發探測) |
| SO_LINGER | struct linger | 控制 close/shutdown 行為: l_onoff=1, l_linger=0 → 立即發 RST (硬關閉) l_onoff=1, l_linger>0 → 等待資料發送完畢或超時 |
| SO_RCVBUF / SO_SNDBUF | int | 接收/發送緩衝區大小(雙向調整,核心會加倍) |
| SO_RCVTIMEO / SO_SNDTIMEO | struct timeval | 接收/發送超時,避免無限阻塞 |
| SO_BROADCAST | int | 允許發送廣播封包 (UDP) |
| SO_OOBINLINE | int | 帶外資料放入正常資料流 (不產生 SIGURG) |
| SO_ERROR | int | 取得並清除 Socket 錯誤狀態 (僅 getsockopt) |
| SO_TYPE | int | 取得 Socket 類型 (SOCK_STREAM/DGRAM) (僅 getsockopt) |
| SO_DEBUG | int | 啟用除錯資訊記錄 (需核心支援) |
| SO_DONTROUTE | int | 繞過路由表 (同 MSG_DONTROUTE) |
IPPROTO_IP 選項
| 選項 | 類型 | 說明 |
| IP_HDRINCL | int | 原始 Socket 自行構造 IP Header |
| IP_TOS | int | 設定服務類型 (QoS/DSCP) |
| IP_TTL | int | 設定封包生存時間 (跳數) |
| IP_MULTICAST_IF / TTL / LOOP | struct in_addr / int | 多播介面、TTL、本地回環控制 |
| IP_ADD_MEMBERSHIP / DROP_MEMBERSHIP | struct ip_mreq | 加入/離開多播群組 |
IPPROTO_TCP 選項
| 選項 | 類型 | 說明 |
| TCP_NODELAY | int | 關閉 Nagle 演算法,立即發送小封包 (低延遲場景) |
| TCP_MAXSEG | int | 設定/取得 MSS (最大段大小) |
| TCP_CORK | int | 啟用 Corking,累積小寫入再一次發送 (高吞吐) |
| TCP_KEEPIDLE / INTVL / CNT | int | 保活參數:空閒時間、探測間隔、探測次數 (Linux 專有) |
| TCP_INFO | struct tcp_info | 取得詳細連線狀態 (cwnd, rtt, 重傳次數等) (僅 getsockopt) |
| TCP_CONGESTION | char[] | 設定/取得阻塞控制演算法 (cubic, bbr 等) |
ioctl 常用 Socket 命令
| 命令 | 說明 |
| FIONREAD | 取得接收緩衝區可讀位元組數 (int *) |
| SIOCATMARK | 判斷是否位於帶外標記位置 (int *) |
| SIOCGIFADDR / SIOCSIFADDR | 取得/設定介面 IP 位址 (struct ifreq) |
| SIOCGIFFLAGS / SIOCSIFFLAGS | 取得/設定介面旗標 (UP, BROADCAST, PROMISC 等) |
| SIOCGIFHWADDR | 取得介面 MAC 位址 |
| SIOCGIFINDEX | 取得介面索引值 |
使用範例
// 設定 SO_REUSEADDR
int opt = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
// 讀取 TCP 狀態資訊
struct tcp_info info;
socklen_t len = sizeof(info);
getsockopt(sockfd, IPPROTO_TCP, TCP_INFO, &info, &len);
printf("cwnd=%u, rtt=%u us\n", info.tcpi_snd_cwnd, info.tcpi_rtt);
// 設定非阻塞 (fcntl 更常用)
int flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);
注意事項
- 選項值類型不匹配導致未定義行為,嚴格對照表格。
- 部分選項需核心編譯支援 (如
TCP_CONGESTION 需 CONFIG_TCP_CONG_*)。
setsockopt 必須在 listen()/connect() 前調用才生效 (如 TCP_NODELAY)。
- 跨平台程式碼應使用
#ifdef 判斷選項是否存在。