為支援後續 ICMP 應用程式開發,本文整理 Winsock 核心函數用法,作為快速查閱手冊。詳細參數與錯誤碼請參考 MSDN 文件。
// 載入 Winsock DLL,協商版本
int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
// 釋放 Winsock 資源
int WSACleanup(void);
// 建立 Socket 描述子
SOCKET socket(int af, int type, int protocol);
// af: AF_INET (IPv4)
// type: SOCK_STREAM (TCP) / SOCK_DGRAM (UDP) / SOCK_RAW (原始)
// protocol: IPPROTO_TCP / IPPROTO_UDP / IPPROTO_ICMP
// 點分十進制字串 → 32-bit 網路序 IP
unsigned long inet_addr(const char *cp);
// 主機名稱 → hostent 結構 (含 IP 清單)
struct hostent *gethostbyname(const char *name);
// 接收資料 (阻塞模式下等待資料到達)
int recv(SOCKET s, char *buf, int len, int flags);
// flags: MSG_PEEK (窺視不移除) / MSG_OOB (帶外資料)
// 回傳: >0 收到位元組數, 0 連線關閉, SOCKET_ERROR 失敗
// 發送資料至指定位址
int sendto(SOCKET s, const char *buf, int len, int flags,
const struct sockaddr *to, int tolen);
// flags: MSG_DONTROUTE (繞過路由) / MSG_OOB
// 回傳: 實際發送位元組數或 SOCKET_ERROR
// 接收資料並取得來源位址
int recvfrom(SOCKET s, char *buf, int len, int flags,
struct sockaddr *from, int *fromlen);
WaitForMultipleObjects 實現高效能伺服器
struct sockaddr_in {
short sin_family; // AF_INET
u_short sin_port; // 網路序埠號
struct in_addr sin_addr; // IP 位址
char sin_zero[8]; // 填充對齊
};
struct in_addr {
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr; // 32-bit IP (網路序)
} S_un;
};
掌握上述 API 即可進行基礎網路程式開發,後續文章將實際應用於 RAW Socket Ping 及 Traceroute 實作。