diff --git a/client/client b/client/client index 84d945e..2e727e4 100755 Binary files a/client/client and b/client/client differ diff --git a/client/client.cpp b/client/client.cpp index b2ca951..9526df3 100644 --- a/client/client.cpp +++ b/client/client.cpp @@ -33,6 +33,12 @@ void* recieve(void* arg) { if (recieved == 0) { std::cout << "Server shutted down" << std::endl; close(client_socket); + if (client_socket1 == client_socket) { + client_socket1 = -1; + } + if (client_socket2 == client_socket) { + client_socket2 = -1; + } break; } @@ -46,13 +52,20 @@ void* recieve(void* arg) { return nullptr; } +struct timer_payload { + int client_socket; + std::string msg; +}; + void* timer(void* arg) { - int client_socket = *(int*)arg; - delete (int*)arg; + timer_payload payload = *(timer_payload*)arg; + + int client_socket = payload.client_socket; + std::string msg = payload.msg; while (true) { - send(client_socket, "", 1, 0); - std::this_thread::sleep_for(std::chrono::seconds(1)); + send(client_socket, msg.c_str(), msg.length(), 0); + std::this_thread::sleep_for(std::chrono::seconds(3)); } return nullptr; @@ -72,6 +85,10 @@ int main() { if(command == "quit") { break; } else if (command == "connect1") { + if (client_socket1 != -1) { + std::cout << "Server is already connected" << std::endl; + continue; + } client_socket1 = socket(AF_INET, SOCK_STREAM, 0); sockaddr_in server_address1; server_address1.sin_family = AF_INET; @@ -86,6 +103,10 @@ int main() { std::cout << "Failed to connect " << std::strerror(errno) << std::endl; } } else if (command == "connect2") { + if (client_socket2 != -1) { + std::cout << "Server is already connected" << std::endl; + continue; + } client_socket2 = socket(AF_INET, SOCK_STREAM, 0); sockaddr_in server_address2; server_address2.sin_family = AF_INET; @@ -129,21 +150,32 @@ int main() { std::cout << "Server is not connected" << std::endl; } } else if (command == "send1") { - if (send(client_socket1, "", 1, 0) == -1) { + std::cout << "Enter the message: "; + std::string msg; + std::cin >> msg; + if (send(client_socket1, msg.c_str(), msg.length(), 0) == -1) { std::cout << "Server is not connected" << std::endl; } else { std::cout << "Message sent" << std::endl; } } else if (command == "send2") { - if (send(client_socket2, "", 1, 0) == -1) { + std::cout << "Enter the message: "; + std::string msg; + std::cin >> msg; + if (send(client_socket2, msg.c_str(), msg.length(), 0) == -1) { std::cout << "Server is not connected" << std::endl; } else { std::cout << "Message sent" << std::endl; } } else if (command == "timer1") { if (client_socket1 != -1) { - int* client_socket_copy1 = new int(client_socket1); - pthread_create(&t1, nullptr, &timer, client_socket_copy1); + std::cout << "Enter the message: "; + std::string msg; + std::cin >> msg; + struct timer_payload p; + p.client_socket = client_socket1; + p.msg = msg; + pthread_create(&t1, nullptr, &timer, &p); pthread_detach(t1); std::cout << "Timer created" << std::endl; } else { @@ -151,8 +183,13 @@ int main() { } } else if (command == "timer2") { if (client_socket2 != -1) { - int* client_socket_copy2 = new int(client_socket2); - pthread_create(&t2, nullptr, &timer, client_socket_copy2); + std::cout << "Enter the message: "; + std::string msg; + std::cin >> msg; + struct timer_payload p; + p.client_socket = client_socket2; + p.msg = msg; + pthread_create(&t2, nullptr, &timer, &p); pthread_detach(t2); std::cout << "Timer created" << std::endl; } else { diff --git a/log_data/2024-12-14.log b/log_data/2024-12-14.log new file mode 100644 index 0000000..eb41eab --- /dev/null +++ b/log_data/2024-12-14.log @@ -0,0 +1,14 @@ +2024/12/14 02:47:49 Socket created +2024/12/14 02:47:58 Socket created +2024/12/14 02:48:44 New thread created for socket 4 +2024/12/14 02:48:55 Got new message from client 4 +2024/12/14 02:49:26 Got new message from client 4 +2024/12/14 02:49:26 Sent new info to client +2024/12/14 02:50:05 Socket created +2024/12/14 02:50:08 New thread created for socket 4 +2024/12/14 02:50:17 Got new message from client 4 +2024/12/14 02:50:17 uwu +2024/12/14 02:50:27 Got new message from client 4 +2024/12/14 02:51:36 Connection with client 4 closed +2024/12/14 02:51:56 Socket created +2024/12/14 02:51:58 Socket created diff --git a/server1/server b/server1/server index bd1fd71..df76df4 100755 Binary files a/server1/server and b/server1/server differ diff --git a/server1/server.cpp b/server1/server.cpp index bd72f74..44afb39 100644 --- a/server1/server.cpp +++ b/server1/server.cpp @@ -50,8 +50,8 @@ std::string last_log_messages[CMD_LOG_BUFFER]; // Amount of active client sessions served by different threads int active_connections = 0; -// Total amount of handled requests -int handndled_requests = 0; +// Mutex to change counter +pthread_mutex_t conn_mutex; // Log pipe file descriptor int is_log_ok = false; @@ -71,40 +71,10 @@ std::string get_last_error() { return "Last error: " + std::to_string(error_code) + " - " + error_description + "\n"; } -// void disable_buffering() { -// struct termios t; -// tcgetattr(STDIN_FILENO, &t); // Get the terminal settings -// t.c_lflag &= ~ICANON; // Disable canonical mode (no buffering) -// t.c_lflag &= ~ECHO; // Disable echo (no terminal output) -// t.c_cc[VMIN] = 1; // Set the minimum number of characters to read (1 char) -// t.c_cc[VTIME] = 0; // Disable timeout -// tcsetattr(STDIN_FILENO, TCSANOW, &t); // Apply the new settings -// } - -// void restore_buffering() { -// struct termios t; -// tcgetattr(STDIN_FILENO, &t); // Get the terminal settings -// t.c_lflag |= ICANON; // Enable canonical mode (buffering) -// t.c_lflag |= ECHO; // Enable echo -// tcsetattr(STDIN_FILENO, TCSANOW, &t); // Apply the restored settings -// } - // Returns info about current cursor position in console std::string get_cursor_position() { int x, y; - // // Disable buffering - // disable_buffering(); - - // printf("\033[6n"); // Request cursor position - // scanf("\033[%d;%dR", &x, &y); // Read cursor position - - // // Print the cursor position - // printf("Cursor position: (%d, %d)\n", x, y); - - // // Restore the terminal settings - // restore_buffering(); - getyx(stdscr, y, x); return "Cursor position: y: " + std::to_string(y) + " x: " + std::to_string(x) + "\n"; @@ -172,14 +142,6 @@ std::string get_vmem() { return "Virtual memory of the proccess: " + std::to_string(100.0 * not_free_mem/total_mem) + "%\n"; } -// Returns message to send according to the server type -std::string get_sysinfo() { - if (SERVER_TYPE == "server1") { - return '\t' + get_last_error() + "\t\t\t" + get_cursor_position(); - } - return '\t' + get_mem_percent() + "\t\t\t" + get_vmem(); // TODO: vmem -} - // Writes log message on screen and passes it to the logging pipe void log(std::string msg) { // Add log message to the screen buffer @@ -242,19 +204,22 @@ void* handle_connection(void* arg) { int client_socket = *(int*)arg; delete (int*)arg; - std::string info = ""; + std::string info1 = ""; + std::string info2 = ""; log("New thread created for socket " + std::to_string(client_socket) + '\0'); while (true) { // Recieve message from client - char buffer[5]; + char buffer[128]; ssize_t bytes_recieved = recv(client_socket, buffer, sizeof(buffer), 0); - + // If connection closed if (bytes_recieved == 0) { log("Connection with client " + std::to_string(client_socket) + " closed"); + pthread_mutex_lock(&conn_mutex); active_connections--; + pthread_mutex_unlock(&conn_mutex); break; } @@ -265,22 +230,57 @@ void* handle_connection(void* arg) { log("Got new message from client " + std::to_string(client_socket) + '\0'); - std::string new_info = get_sysinfo(); + std::string new_info, req = std::string(buffer); + log(req + '\0'); - if (info != new_info) { - info = new_info; - time_t now = time(0); - struct tm tstruct; - tstruct = *localtime(&now); - char timestamp[32]; - std::strftime(timestamp, 32, "%Y/%m/%d %H:%M:%S ", &tstruct); - std::string msg = timestamp + info; - send(client_socket, msg.c_str(), strlen(msg.c_str()) + 1, 0); - log("Sent new info to client\0"); - handndled_requests++; - } else { - log("Actual info already on client\0"); + if (SERVER_TYPE == "server1") { + if (req == "last_error") { + new_info = get_last_error(); + if (new_info == info1) { + log("Actual info already on client\0"); + continue; + } + info1 = new_info; + } else if (req == "cursor_position") { + new_info = get_cursor_position(); + if (new_info == info2) { + log("Actual info already on client\0"); + continue; + } + info2 = new_info; + } else { + new_info = "Invalid request. Available options: last_error, cursor_position"; + } } + + if (SERVER_TYPE == "server2") { + if (req == "mem") { + new_info = get_mem_percent(); + if (new_info == info1) { + log("Actual info already on client\0"); + continue; + } + info1 = new_info; + } else if (req == "vmem") { + new_info = get_vmem(); + if (new_info == info2) { + log("Actual info already on client\0"); + continue; + } + info2 = new_info; + } else { + new_info = "Invalid request. Available options: mem, vmem"; + } + } + + time_t now = time(0); + struct tm tstruct; + tstruct = *localtime(&now); + char timestamp[32]; + std::strftime(timestamp, 32, "%Y/%m/%d %H:%M:%S ", &tstruct); + std::string msg = timestamp + new_info; + send(client_socket, msg.c_str(), strlen(msg.c_str()) + 1, 0); + log("Sent new info to client\0"); } close(client_socket); @@ -298,8 +298,8 @@ void* draw(void* arg) { // Print configuration printw( - "LOG_FIFO_NAME=%s\nSERVER_TYPE=%s\nPORT=%i\nMAX_CONNECTIONS=%i\nCMD_LOG_BUFFER=%i\nCMD_REFRESH_TIME=%i\n\n", - LOG_FIFO_NAME.c_str(), SERVER_TYPE.c_str(), PORT, MAX_CONNECTIONS, CMD_LOG_BUFFER, CMD_REFRESH_TIME + "LOG_FIFO_NAME=%s\nSERVER_TYPE=%s\nPORT=%i\nCMD_LOG_BUFFER=%i\nCMD_REFRESH_TIME=%i\n\n", + LOG_FIFO_NAME.c_str(), SERVER_TYPE.c_str(), PORT, CMD_LOG_BUFFER, CMD_REFRESH_TIME ); if (is_log_ok) { @@ -309,7 +309,7 @@ void* draw(void* arg) { } // Print statistics - printw("Active connections: %i\nHandled messages: %i\n", active_connections, handndled_requests); + printw("Active connections: %i\n", active_connections); // Print logs for (int i = CMD_LOG_BUFFER-1; i >= 0; i--) { @@ -380,7 +380,9 @@ int main() { continue; } + pthread_mutex_lock(&conn_mutex); active_connections++; + pthread_mutex_unlock(&conn_mutex); // Create thread for each connection int* client_socket_copy = new int(client_socket); diff --git a/server2/server b/server2/server index a3d07ba..4eb930e 100755 Binary files a/server2/server and b/server2/server differ diff --git a/server2/server.cpp b/server2/server.cpp index ea86c4c..f738e5d 100644 --- a/server2/server.cpp +++ b/server2/server.cpp @@ -50,8 +50,8 @@ std::string last_log_messages[CMD_LOG_BUFFER]; // Amount of active client sessions served by different threads int active_connections = 0; -// Total amount of handled requests -int handndled_requests = 0; +// Mutex to change counter +pthread_mutex_t conn_mutex; // Log pipe file descriptor int is_log_ok = false; @@ -71,40 +71,10 @@ std::string get_last_error() { return "Last error: " + std::to_string(error_code) + " - " + error_description + "\n"; } -// void disable_buffering() { -// struct termios t; -// tcgetattr(STDIN_FILENO, &t); // Get the terminal settings -// t.c_lflag &= ~ICANON; // Disable canonical mode (no buffering) -// t.c_lflag &= ~ECHO; // Disable echo (no terminal output) -// t.c_cc[VMIN] = 1; // Set the minimum number of characters to read (1 char) -// t.c_cc[VTIME] = 0; // Disable timeout -// tcsetattr(STDIN_FILENO, TCSANOW, &t); // Apply the new settings -// } - -// void restore_buffering() { -// struct termios t; -// tcgetattr(STDIN_FILENO, &t); // Get the terminal settings -// t.c_lflag |= ICANON; // Enable canonical mode (buffering) -// t.c_lflag |= ECHO; // Enable echo -// tcsetattr(STDIN_FILENO, TCSANOW, &t); // Apply the restored settings -// } - // Returns info about current cursor position in console std::string get_cursor_position() { int x, y; - // // Disable buffering - // disable_buffering(); - - // printf("\033[6n"); // Request cursor position - // scanf("\033[%d;%dR", &x, &y); // Read cursor position - - // // Print the cursor position - // printf("Cursor position: (%d, %d)\n", x, y); - - // // Restore the terminal settings - // restore_buffering(); - getyx(stdscr, y, x); return "Cursor position: y: " + std::to_string(y) + " x: " + std::to_string(x) + "\n"; @@ -172,14 +142,6 @@ std::string get_vmem() { return "Virtual memory of the proccess: " + std::to_string(100.0 * not_free_mem/total_mem) + "%\n"; } -// Returns message to send according to the server type -std::string get_sysinfo() { - if (SERVER_TYPE == "server1") { - return '\t' + get_last_error() + "\t\t\t" + get_cursor_position(); - } - return '\t' + get_mem_percent() + "\t\t\t" + get_vmem(); // TODO: vmem -} - // Writes log message on screen and passes it to the logging pipe void log(std::string msg) { // Add log message to the screen buffer @@ -211,12 +173,14 @@ void log(std::string msg) { // Returns file descriptor for server socket int start_socket() { + int option = 1; int server_socket = socket(AF_INET, SOCK_STREAM, 0); + setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)); + sockaddr_in server_address; server_address.sin_family = AF_INET; server_address.sin_port = htons(PORT); server_address.sin_addr.s_addr = INADDR_ANY; - bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address)); if (errno == 98) { @@ -240,19 +204,22 @@ void* handle_connection(void* arg) { int client_socket = *(int*)arg; delete (int*)arg; - std::string info = ""; + std::string info1 = ""; + std::string info2 = ""; log("New thread created for socket " + std::to_string(client_socket) + '\0'); while (true) { // Recieve message from client - char buffer[5]; + char buffer[128]; ssize_t bytes_recieved = recv(client_socket, buffer, sizeof(buffer), 0); - + // If connection closed if (bytes_recieved == 0) { log("Connection with client " + std::to_string(client_socket) + " closed"); + pthread_mutex_lock(&conn_mutex); active_connections--; + pthread_mutex_unlock(&conn_mutex); break; } @@ -263,22 +230,57 @@ void* handle_connection(void* arg) { log("Got new message from client " + std::to_string(client_socket) + '\0'); - std::string new_info = get_sysinfo(); + std::string new_info, req = std::string(buffer); + log(req); - if (info != new_info) { - info = new_info; - time_t now = time(0); - struct tm tstruct; - tstruct = *localtime(&now); - char timestamp[32]; - std::strftime(timestamp, 32, "%Y/%m/%d %H:%M:%S ", &tstruct); - std::string msg = timestamp + info; - send(client_socket, msg.c_str(), strlen(msg.c_str()) + 1, 0); - log("Sent new info to client\0"); - handndled_requests++; - } else { - log("Actual info already on client\0"); + if (SERVER_TYPE == "server1") { + if (req == "last_error") { + new_info = get_last_error(); + if (new_info == info1) { + log("Actual info already on client\0"); + continue; + } + info1 = new_info; + } else if (req == "cursor_position") { + new_info = get_cursor_position(); + if (new_info == info2) { + log("Actual info already on client\0"); + continue; + } + info2 = new_info; + } else { + new_info = "Invalid request. Available options: last_error, cursor_position"; + } } + + if (SERVER_TYPE == "server2") { + if (req == "mem") { + new_info = get_mem_percent(); + if (new_info == info1) { + log("Actual info already on client\0"); + continue; + } + info1 = new_info; + } else if (req == "vmem") { + new_info = get_vmem(); + if (new_info == info2) { + log("Actual info already on client\0"); + continue; + } + info2 = new_info; + } else { + new_info = "Invalid request. Available options: mem, vmem"; + } + } + + time_t now = time(0); + struct tm tstruct; + tstruct = *localtime(&now); + char timestamp[32]; + std::strftime(timestamp, 32, "%Y/%m/%d %H:%M:%S ", &tstruct); + std::string msg = timestamp + new_info; + send(client_socket, msg.c_str(), strlen(msg.c_str()) + 1, 0); + log("Sent new info to client\0"); } close(client_socket); @@ -296,8 +298,8 @@ void* draw(void* arg) { // Print configuration printw( - "LOG_FIFO_NAME=%s\nSERVER_TYPE=%s\nPORT=%i\nMAX_CONNECTIONS=%i\nCMD_LOG_BUFFER=%i\nCMD_REFRESH_TIME=%i\n\n", - LOG_FIFO_NAME.c_str(), SERVER_TYPE.c_str(), PORT, MAX_CONNECTIONS, CMD_LOG_BUFFER, CMD_REFRESH_TIME + "LOG_FIFO_NAME=%s\nSERVER_TYPE=%s\nPORT=%i\nCMD_LOG_BUFFER=%i\nCMD_REFRESH_TIME=%i\n\n", + LOG_FIFO_NAME.c_str(), SERVER_TYPE.c_str(), PORT, CMD_LOG_BUFFER, CMD_REFRESH_TIME ); if (is_log_ok) { @@ -307,7 +309,7 @@ void* draw(void* arg) { } // Print statistics - printw("Active connections: %i\nHandled messages: %i\n", active_connections, handndled_requests); + printw("Active connections: %i\n", active_connections); // Print logs for (int i = CMD_LOG_BUFFER-1; i >= 0; i--) { @@ -353,6 +355,12 @@ int main() { int server_socket = start_socket(); + if (server_socket == -1) { + getch(); + endwin(); + return 3; + } + log("Socket created\0"); // Create thread to read commands @@ -372,7 +380,9 @@ int main() { continue; } + pthread_mutex_lock(&conn_mutex); active_connections++; + pthread_mutex_unlock(&conn_mutex); // Create thread for each connection int* client_socket_copy = new int(client_socket);