#include "server_heartbeat.h" #include #include #include "spdlog/spdlog.h" namespace Heartbeat { // 配置常量实现 const int PORT = 8888; const int TIMEOUT = 15; const int HEARTBEAT_INTERVAL = 10; // 全局变量 std::vector clients; std::mutex clients_mutex; // 主函数实现 void start_server() { int server_sock = -1; sockaddr_in server_addr = {}; if (!initialize_socket(server_sock)) { return; } bind_socket(server_sock, server_addr); listen_for_connections(server_sock); accept_connections(server_sock); close(server_sock); } bool initialize_socket(int& server_sock) { server_sock = socket(AF_INET, SOCK_STREAM, 0); if (server_sock < 0) { perror("Socket creation failed"); return false; } int opt = 1; if (setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) { perror("Setsockopt failed"); close(server_sock); return false; } spdlog::info("Heartbeat program started."); return true; } void bind_socket(int server_sock, sockaddr_in& server_addr) { server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(PORT); if (bind(server_sock, (sockaddr*)&server_addr, sizeof(server_addr)) < 0) { perror("Bind failed"); close(server_sock); exit(EXIT_FAILURE); } } void listen_for_connections(int server_sock) { if (listen(server_sock, 5) < 0) { perror("Listen failed"); close(server_sock); exit(EXIT_FAILURE); } std::cout << "Server started on port " << PORT << std::endl; } void accept_connections(int server_sock) { while (true) { sockaddr_in client_addr; socklen_t client_len = sizeof(client_addr); int client_sock = accept(server_sock, (sockaddr*)&client_addr, &client_len); if (client_sock < 0) { perror("Accept failed"); continue; } std::cout << "[+] New client connected: " << client_sock << std::endl; { std::lock_guard lock(clients_mutex); clients.push_back(client_sock); } std::thread(handle_client, client_sock, client_addr).detach(); std::thread(send_heartbeat, client_sock).detach(); } } void send_heartbeat(int client_sock) { while (true) { send(client_sock, "KEEP_ALIVE", 10, 0); sleep(HEARTBEAT_INTERVAL); } } void handle_client(int client_sock, sockaddr_in addr) { char buffer[1024] = {0}; fd_set read_fds; struct timeval timeout; while (true) { FD_ZERO(&read_fds); FD_SET(client_sock, &read_fds); timeout.tv_sec = 1; timeout.tv_usec = 0; int activity = select(client_sock + 1, &read_fds, NULL, NULL, &timeout); if (activity < 0) { perror("select error"); break; } if (FD_ISSET(client_sock, &read_fds)) { int bytes_read = recv(client_sock, buffer, 1024, 0); if (bytes_read <= 0) { break; } if (strncmp(buffer, "ALIVE", 5) == 0) { std::cout << "[RECV] Client " << client_sock << " sent ALIVE" << std::endl; } } } cleanup_disconnected(client_sock); close(client_sock); std::cout << "[-] Client " << client_sock << " disconnected" << std::endl; } void cleanup_disconnected(int client_sock) { std::lock_guard lock(clients_mutex); auto it = std::remove(clients.begin(), clients.end(), client_sock); clients.erase(it, clients.end()); } } // namespace Heartbea // 111 // 主函数入口 // int main() { // Heartbeat::start_server(); // return 0; // }