#include<stdio.h> #include<iostream> #include<WinSock2.h> // 包含网络编程头文件,链接静态库 #pragma comment(lib,"ws2_32.lib") #include<process.h>//多线程相关 #include<string> // 为了使用 std::string #include<sstream> // 为了使用 std::stringstream using namespace std; unsigned WINAPI RequestHandler(void* arg); int merror(int redata, int error, const char* showinfo); void sendJsonResponse(SOCKET s, const string& jsonResponse); void handleRequest(SOCKET client, const string& request); void sendhtml(SOCKET s, char* filename); // 提前声明sendhtml函数 int main() { DWORD dwThreadTD; printf("welcome to my web server!\n"); WSADATA wsdata; int is_ok = WSAStartup(MAKEWORD(2, 2), &wsdata); // 确定socket版本信息 if (merror(is_ok, WSAEINVAL, "申请socket失败!") != 0) return -1; SOCKET server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // af_inet使用ipv4地址 if (merror(server, INVALID_SOCKET, "创建socket失败") != 0) return -1; SOCKADDR_IN seraddr; seraddr.sin_family = AF_INET; // 和创建时一样 ipv4 seraddr.sin_port = htons(80); //网络是大端存储, pc是小端存储,需要转换 seraddr.sin_addr.s_addr = INADDR_ANY; // 监听任意地址 is_ok = bind(server, (SOCKADDR*)&seraddr, sizeof(seraddr)); if (merror(is_ok, SOCKET_ERROR, "socket绑定失败!") != 0) return -1; is_ok = listen(server, 5); // 客户端连接数量 if (merror(is_ok, SOCKET_ERROR, "监听失败!") != 0) return -1; SOCKADDR_IN claddr; // 客户端信息 int cllen = sizeof(claddr); while (1) { SOCKET client = accept(server, (SOCKADDR*)&claddr, &cllen); // 谁连进来了 if (merror(client, INVALID_SOCKET, "连接失败!") != 0) continue; // 开启新线程处理请求 HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, RequestHandler, (void*)client, 0, (unsigned*)&dwThreadTD); } closesocket(server); WSACleanup(); getchar(); return 0; } unsigned WINAPI RequestHandler(void* arg) { SOCKET client = (SOCKET)arg; char recvData[1024] = ""; int recvLen = recv(client, recvData, 1024, 0); if (recvLen > 0) { string request(recvData, recvLen); cout << "接收到的请求:" << endl; cout << request << endl; // 打印完整的请求内容 handleRequest(client, request); } closesocket(client); return 0; } void handleRequest(SOCKET client, const string& request) { size_t methodEnd = request.find(' '); if (methodEnd != string::npos) { string method = request.substr(0, methodEnd); if (method == "POST" || method == "PUT" || method == "DELETE") { size_t jsonStart = request.find("\r\n\r\n"); if (jsonStart != string::npos) { string jsonData = request.substr(jsonStart + 4); // Skip past \r\n\r\n cout << "接收到的数据:" << jsonData << endl; cout<<endl; cout<<endl; // 打印请求的具体内容 // 手动构造JSON响应 string jsonResponse = "{\"status\":\"success\",\"data\":" + jsonData + "}"; sendJsonResponse(client, jsonResponse); } } else { // 处理其他请求,默认为返回index.html sendhtml(client, (char*)"index.html"); } } } void sendJsonResponse(SOCKET s, const string& jsonResponse) { string protocol = "HTTP/1.0 200 OK\r\n"; string serverName = "Server: Simple Web Server\r\n"; string contentType = "Content-Type: application/json\r\n"; // 使用 stringstream 替代 std::to_string stringstream ss; ss << "Content-Length: " << jsonResponse.size() << "\r\n\r\n"; string contentLength = ss.str(); send(s, protocol.c_str(), protocol.size(), 0); send(s, serverName.c_str(), serverName.size(), 0); send(s, contentType.c_str(), contentType.size(), 0); send(s, contentLength.c_str(), contentLength.size(), 0); send(s, jsonResponse.c_str(), jsonResponse.size(), 0); } void sendhtml(SOCKET s, char* filename) { char protocol[] = "HTTP/1.0 200 OK\r\n"; char serName[] = "Server: Simple Web Server\r\n"; char cntType[] = "Content-Type: text/html\r\n\r\n"; send(s, protocol, strlen(protocol), 0); send(s, serName, strlen(serName), 0); send(s, cntType, strlen(cntType), 0); FILE* pfile = fopen(filename, "r"); if (pfile == NULL) { cout << "can not open the file!" << endl; return; } char temp[1024] = ""; do { fgets(temp, 1024, pfile); send(s, temp, strlen(temp), 0); } while (!feof(pfile)); fclose(pfile); } int merror(int redata, int error, const char* showinfo) { if (redata == error) { perror(showinfo); getchar(); return -1; } return 0; }