本文依據 1993 年 Winsock 1.1 規範,詳細說明三個關鍵網路程式設計 API:網址轉換、Socket 模式控制、監聽佇列管理。
char FAR * PASCAL FAR inet_ntoa(struct in_addr in);
參數:in - 包含 IPv4 位址的 in_addr 結構 (s_addr 為網路序 32-bit 整數)。
回傳:
"a.b.c.d" (如 "192.168.1.1")NULL關鍵注意:
InetNtop (IPv6 相容)in_addr 必須為網路位元組序 (大端序),主機序需先 htonlgetnameinfo 或 InetNtopint PASCAL FAR ioctlsocket(SOCKET s, long cmd, u_long FAR *argp);
參數:s Socket 描述符,cmd 控制碼,argp 參數指標。
回傳:0 成功,SOCKET_ERROR 失敗 (呼叫 WSAGetLastError 取得錯誤碼)。
支援控制碼:
| cmd | 功能 | argp 用途 |
|---|---|---|
FIONBIO | 啟用/停用非阻塞模式 | 指向 u_long:非零=非阻塞,零=阻塞 |
FIONREAD | 取得可立即讀取的資料位元組數 | 指向 u_long 接收回傳值 |
SIOCATMARK | OOB 資料是否已讀完 | 指向 u_long (Winsock 1.1 暫不支援) |
非阻塞模式典型用法:
u_long mode = 1; // 1 = 非阻塞
ioctlsocket(s, FIONBIO, &mode);
配合 select 實現高併發 I/O 多路複用。
int PASCAL FAR listen(SOCKET s, int backlog);
參數:
s:已 bind 且未 connect 的 Socket (通常為 SOCK_STREAM)backlog:待接受連線佇列最大長度回傳:0 成功,SOCKET_ERROR 失敗。
關鍵語意:
backlog 定義「已完成三向交握但尚未 accept」的連線上限SOMAXCONN 由系統決定backlog 的新連線請求,用戶端收到 ECONNREFUSED 或被悄悄丟棄bind 之後、accept 之前呼叫SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
bind(s, (sockaddr*)&addr, sizeof(addr));
listen(s, 5); // 進入監聽狀態
// 非阻塞模式 (可選)
u_long nonblock = 1;
ioctlsocket(s, FIONBIO, &nonblock);
// 接受迴圈
while (running) {
SOCKET client = accept(s, &cliAddr, &len);
if (client != INVALID_SOCKET) {
char *ip = inet_ntoa(cliAddr.sin_addr); // 顯示客戶端 IP
// 建立工作執行緒處理 client...
}
}
inet_ntoa → InetNtop(AF_INET, &addr, buf, sizeof(buf)) (執行緒安全、支援 IPv6)ioctlsocket(FIONBIO) → fcntl(fd, F_SETFL, O_NONBLOCK) (POSIX) 或 WSAIoctl (擴展功能)listen(backlog) → 使用 SOMAXCONN 讓系統自動調優IOCP (I/O Completion Ports) + AcceptEx/GetAcceptExSockaddrs理解經典 API 運作機制,是掌握現代網路框架 (libuv, Boost.Asio, Netty) 底層原理的基石。