核心流程
- Socket 初始化:
WSAStartup、socket、bind、listen。
- 接受連接:
accept 獲取客戶端 Socket。
- 接收請求:
recv 讀取 HTTP 報文(請求行、Headers、Body)。
- 解析請求:提取 Method、Path、Query Params、Headers、Body。
- 路由分發:根據 Path/Method 調用對應處理函數。
- 構建響應:狀態行、Headers、Body(HTML/JSON)。
- 發送響應:
send,關閉連接(HTTP/1.0)或保持長連接。
最小實現示例(同步阻塞)
#include
#include
#pragma comment(lib, "ws2_32.lib")
std::string handleRequest(const std::string& req) {
// 簡易解析 GET /api?key=value
if (req.find("GET /api") == 0) {
size_t q = req.find('?');
std::string param = (q != std::string::npos) ? req.substr(q+1) : "";
return "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{\"received\":\"" + param + "\"}";
}
return "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>Hello</h1>";
}
int main() {
WSADATA wsa; WSAStartup(MAKEWORD(2,2), &wsa);
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sockaddr_in addr = {AF_INET, htons(8080), INADDR_ANY};
bind(s, (sockaddr*)&addr, sizeof(addr));
listen(s, SOMAXCONN);
printf("Server running on port 8080...\n");
while (true) {
SOCKET c = accept(s, NULL, NULL);
char buf[4096]; int len = recv(c, buf, sizeof(buf)-1, 0);
if (len > 0) { buf[len] = 0; std::string resp = handleRequest(buf); send(c, resp.c_str(), resp.size(), 0); }
closesocket(c);
}
closesocket(s); WSACleanup();
return 0;
}
擴展建議
- 使用
IOCP 或 select/poll 實現高併發。
- 引入
cpp-httplib、Restinio 等現代 C++ HTTP 庫避免重複造輪子。
- 解析 POST Body 需處理
Content-Length、Transfer-Encoding: chunked。