bonus-edge-proxy/src/archive/server_heartbeat.cc

149 lines
3.8 KiB
C++

#include "server_heartbeat.h"
#include <cstdio>
#include <cstdlib>
#include "spdlog/spdlog.h"
namespace Heartbeat {
// 配置常量实现
const int PORT = 8888;
const int TIMEOUT = 15;
const int HEARTBEAT_INTERVAL = 10;
// 全局变量
std::vector<int> 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<std::mutex> 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<std::mutex> 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;
// }