網路通訊雙方需協同工作,使用相同傳輸協定(TCP 或 UDP)。一個完整連線由五元組唯一標識:
listen 進入被動等待,accept 接受連線,處理請求後回應。connect 到 Server IP:Port,發送請求,接收回應。WSAStartup:載入 Winsock DLL,協商版本(通常 MAKEWORD(2,2))。socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)。sockaddr_in:sin_family=AF_INET、sin_port=htons(port)、sin_addr.s_addr=inet_addr(ip)。connect;Server:bind → listen → accept。send/recv(TCP);sendto/recvfrom(UDP)。closesocket → WSACleanup。// Server.cpp
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
int main() {
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) return 1;
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET) return 1;
SOCKADDR_IN addr = {0};
addr.sin_family = AF_INET;
addr.sin_port = htons(8888);
addr.sin_addr.s_addr = htonl(INADDR_ANY); // 監聽所有介面
if (bind(s, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR) return 1;
if (listen(s, SOMAXCONN) == SOCKET_ERROR) return 1;
printf("Server listening on port 8888...\n");
while (1) {
SOCKADDR_IN clientAddr;
int addrLen = sizeof(clientAddr);
SOCKET client = accept(s, (SOCKADDR*)&clientAddr, &addrLen);
if (client == INVALID_SOCKET) continue;
printf("Client connected: %s:%d\n",
inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port));
char buf[1024];
int recvLen;
while ((recvLen = recv(client, buf, sizeof(buf)-1, 0)) > 0) {
buf[recvLen] = '\0';
printf("Received: %s\n", buf);
send(client, buf, recvLen, 0); // Echo back
}
closesocket(client);
}
closesocket(s);
WSACleanup();
return 0;
}
// Client.cpp
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
int main() {
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
SOCKADDR_IN addr = {0};
addr.sin_family = AF_INET;
addr.sin_port = htons(8888);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(s, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR) {
printf("Connect failed: %d\n", WSAGetLastError());
return 1;
}
const char *msg = "Hello from Client!";
send(s, msg, (int)strlen(msg), 0);
char buf[1024];
int len = recv(s, buf, sizeof(buf)-1, 0);
if (len > 0) {
buf[len] = '\0';
printf("Server echo: %s\n", buf);
}
closesocket(s);
WSACleanup();
return 0;
}

htons/htonl 轉網路序(Big Endian)。WSAGetLastError()。ioctlsocket(FIONBIO) 或 select/WSAEventSelect/IOCP。shutdown(s, SD_SEND) 發送 FIN,對端 recv 返回 0,再 closesocket。select/WSAAsyncSelect/IOCP 模型比較。Socket 程式設計基石在於理解 TCP 狀態機與 Winsock API 契約。熟練掌握同步阻塞模型後,再進階至高效能非阻塞架構,才能構建穩定、可擴展的網路應用。