在 VC++ 進行網絡編程時,任何使用 Socket 的程序都必須首先調用 WSAStartup 函數來初始化 Windows Sockets 環境。該函數的原型如下:
int WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData
);
參數說明:
wVersionRequested:指定程序請求使用的 Windows Sockets 版本。高位字節為副版本號,低位字節為主版本號。例如請求 2.1 版本時,可使用 MAKEWORD(2, 1) 宏構造。lpWSAData:指向 WSADATA 結構的指針,函數調用成功後,系統會填充該結構,返回實際支持的 Socket 版本信息。工作原理: 當應用程序調用 WSAStartup 時,操作系統會根據請求的版本搜索對應的 Socket 動態鏈接庫(如 ws2_32.dll),並將其綁定到當前進程。之後程序即可調用該庫中導出的各類 Socket 函數(如 socket、connect、send 等)。函數執行成功返回 0,失敗則返回錯誤代碼。
代碼示例:
WORD wVersionRequested = MAKEWORD(2, 1);
WSADATA wsaData;
int err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
// 初始化失敗處理
return -1;
}
// 檢查實際版本是否符合要求
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 1) {
WSACleanup();
return -1;
}
當應用程序完成網絡通信任務,不再需要 Socket 服務時,必須調用 WSACleanup 函數解除與 Socket 庫的綁定,並釋放相關系統資源。其原型為:
int WSACleanup(void);
每次成功調用 WSAStartup 都應對應一次 WSACleanup 調用。在多線程程序中,需確保所有線程都已停止使用 Socket 後再調用此函數,否則可能導致資源洩漏或程序崩潰。
Windows Sockets 提供了一組用於查詢主機名、服務名、協議號等網絡信息的數據庫函數,常用函數包括:
gethostname:獲取本地主機名gethostbyname:根據主機名獲取主機信息(IP 地址列表等)gethostbyaddr:根據 IP 地址獲取主機信息getservbyname / getservbyport:查詢服務名與端口號映射getprotobyname / getprotobynumber:查詢協議信息原型: int PASCAL FAR gethostname(char FAR *name, int namelen);
功能: 獲取本地計算機的主機名稱。
參數:
name(輸出):指向接收主機名的緩衝區指針namelen(輸入):緩衝區大小(字節數)返回值: 成功返回 0,失敗返回 SOCKET_ERROR,可通過 WSAGetLastError() 獲取具體錯誤碼。
原型: struct hostent FAR * PASCAL FAR gethostbyname(const char FAR *name);
功能: 從主機數據庫中查找指定主機名對應的 hostent 結構,包含主機的官方名稱、別名列表、地址類型、地址長度及 IP 地址列表。
參數: name 為主機名(可由 gethostname 獲取或直接指定域名)。
返回值: 成功返回指向 hostent 結構的指針,失敗返回 NULL。
hostent 結構關鍵字段:
struct hostent {
char FAR *h_name; // 官方主機名
char FAR *FAR *h_aliases; // 別名列表
short h_addrtype; // 地址類型(AF_INET)
short h_length; // 地址長度(IPv4 為 4)
char FAR *FAR *h_addr_list; // IP 地址列表(網絡字節序)
};
#define h_addr h_addr_list[0] // 兼容宏,指向第一個 IP 地址
使用提示: 該函數返回的結構指向靜態內存,線程不安全;多線程環境下建議使用 getaddrinfo 替代。