#include #include #include #include #include #include #include #include #include #include #include #define BUFFER_SIZE 1024 #define HTTP_SERVER_PORT 8080 std::vector threads; // 存储所有连接线程 std::map sockets; // 存储套接字 std::mutex sockets_mutex; // 用于同步访问 sockets std::atomic exit_flag(false); // 原子退出标志 // 维护连接的函数 void KeepConnection(int sock) { char buffer[BUFFER_SIZE]; int nbytes; while (!exit_flag) { nbytes = recv(sock, buffer, BUFFER_SIZE, 0); if (nbytes <= 0) { std::cout << "Gateway disconnected" << std::endl; break; } std::cout << "Received from gateway (Socket " << sock << "): " << buffer << std::endl; } { std::lock_guard lock(sockets_mutex); sockets.erase(sock); // 从集合中移除套接字 } close(sock); } // 连接到网关的函数 void ConnectToGateway(const std::string& ip, int port) { int sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { perror("Could not create socket"); return; } struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); if (inet_pton(AF_INET, ip.c_str(), &server_addr.sin_addr) <= 0) { perror("Invalid address"); close(sock); return; } if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("Connection to the server failed"); close(sock); return; } { std::lock_guard lock(sockets_mutex); sockets[sock] = 1; // 将套接字添加到集合中 } std::cout << "Connected to gateway at " << ip << ":" << port << " (Socket " << sock << ")" << std::endl; // 在新线程中维护连接 threads.emplace_back(KeepConnection, sock); } // 处理HTTP请求的函数 void HandleHttpRequest(int client_socket) { char buffer[BUFFER_SIZE]; int bytes_read = recv(client_socket, buffer, sizeof(buffer), 0); if (bytes_read <= 0) { close(client_socket); return; } // 简单解析HTTP请求 std::string http_request(buffer, bytes_read); std::string ip; int port; // 寻找IP和端口号 auto host_pos = http_request.find("Host: "); if (host_pos != std::string::npos) { auto start = host_pos + std::string("Host: ").size(); ip = http_request.substr(start, http_request.find("\r\n", start) - start); } auto content_length_pos = http_request.find("Content-Length:"); if (content_length_pos != std::string::npos) { auto start = content_length_pos + std::string("Content-Length: ").size(); int length = std::stoi(http_request.substr(start, http_request.find("\r\n", start) - start)); if (length > 0) { char* content = new char[length]; bytes_read = recv(client_socket, content, length, 0); if (bytes_read > 0) { // 解析JSON内容(假设前端发送的是JSON格式) // 这里需要添加JSON解析逻辑来提取IP和端口 // 示例:{"ip":"192.168.1.1","port":8080} // 可以使用第三方库如nlohmann/json来解析JSON // 假设解析后得到ip和port // ConnectToGateway(ip, port); delete[] content; } } } // 发送HTTP响应 std::string response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n"; send(client_socket, response.c_str(), response.size(), 0); close(client_socket); } // 启动HTTP服务器的函数 void StartHttpServer() { int http_server_socket = socket(AF_INET, SOCK_STREAM, 0); if (http_server_socket < 0) { perror("Could not create HTTP server socket"); return; } int opt = 1; if (setsockopt(http_server_socket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { perror("Setsockopt failed"); close(http_server_socket); return; } struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(HTTP_SERVER_PORT); if (bind(http_server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("Bind failed"); close(http_server_socket); return; } if (listen(http_server_socket, 5) < 0) { perror("Listen failed"); close(http_server_socket); return; } std::cout << "HTTP server listening on port " << HTTP_SERVER_PORT << std::endl; while (!exit_flag) { int client_socket = accept(http_server_socket, NULL, NULL); if (client_socket < 0) { perror("Accept failed"); continue; } threads.emplace_back(HandleHttpRequest, client_socket); } close(http_server_socket); } int main() { // threads.emplace_back(StartHttpServer); // std::string command, ip; // int port; // bool in_connect_mode = false; // std::cout << "Enter command (connect/exit): "; // while (true) { // if (in_connect_mode) // { // std::cout << "continue connect or not ? (y or n) "; // std::cin >> command; // if(command=="y"){ // std::cout << "Enter the gateway IP address: "; // std::cin >> ip; // std::cout << "Enter the gateway port: "; // std::cin >> port; // ConnectToGateway(ip, port); // } // else { // in_connect_mode = false; // 退出连接模式 // std::cout << "Exiting connect mode." << std::endl; // } // } // else{ // std::cout << "Enter command (connect/exit): "; // std::cin>>command; // if (command == "connect") { // if (in_connect_mode) { // std::cout << "Already in connect mode." << std::endl; // continue; // } // in_connect_mode = true; // 进入连接模式 // std::cout << "Enter the gateway IP address: "; // std::cin >> ip; // std::cout << "Enter the gateway port: "; // std::cin >> port; // ConnectToGateway(ip, port); // } else if (command == "exit") { // exit_flag = true; // 设置退出标志 // std::cout << "Exiting program." << std::endl; // // 关闭所有套接字 // for (auto& sock_pair : sockets) { // shutdown(sock_pair.first, SHUT_RDWR); // 关闭套接字的发送和接收 // close(sock_pair.first); // } // sockets.clear(); // std::cout << "sockets.clear" << std::endl; // // 等待所有线程结束 // for (auto& thread : threads) { // if (thread.joinable()) { // thread.join(); // } // } // threads.clear(); // break; // 退出主循环 // } else { // std::cout << "Unknown command" << std::endl; // } // } // } // std::cout<<"out"<> command; if (command == "connect") { if (in_connect_mode) { std::cout << "Already in connect mode." << std::endl; continue; } in_connect_mode = true; std::cout << "Enter the gateway IP address: "; std::cin >> ip; std::cout << "Enter the gateway port: "; std::cin >> port; ConnectToGateway(ip, port); } else if (command == "exit") { break; // 接收到退出命令,退出主循环 } else { std::cout << "Unknown command" << std::endl; } } // 设置退出标志 exit_flag = true; // 强制结束HTTP服务器线程 if (http_server_thread.joinable()) { http_server_thread.join(); } // 关闭所有套接字 for (auto& sock_pair : sockets) { shutdown(sock_pair.first, SHUT_RDWR); close(sock_pair.first); } sockets.clear(); // 等待所有工作线程结束 for (auto& thread : threads) { if (thread.joinable()) { thread.join(); } } threads.clear(); std::cout << "Exited program." << std::endl; return 0; }