Untitled
unknown
c_cpp
a year ago
9.2 kB
1
Indexable
Never
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h> #include <unistd.h> #include <pthread.h> #include <errno.h> #include <ctype.h> #include <time.h> #define PORT 9003 #define MAX_CLIENTS 10 #define STACK_MAX 10000 // Declaration of functions //char* handle_input ( char *data); double compute_postfix_expression(char *buffer); time_t start, current; // Declaration of two mutex locks for file access synchronization //pthread_mutex_t lock_file = PTHREAD_MUTEX_INITIALIZER; //pthread_mutex_t lock_file2 = PTHREAD_MUTEX_INITIALIZER; // Definition of a struct to hold connection data typedef struct { struct sockaddr_in adres; int address_length; int bind_result; } connect__data; // Definition of a struct to hold arguments for a function struct args { int arg1; int arg2; }; typedef struct { int top; float items[STACK_MAX]; } Stack; // void *handle_client(void *arg) { // // Convert void pointer argument to a struct of two integers // struct args *my_args = (struct args *) arg; // // Extract the two integers from the struct // int i = my_args ->arg1; // i is the client number // int new_socket = my_args -> arg2; // new_socket is the socket descriptor for the client connection // /* --------------------------------------------------------------------------------*/ // // Receive the client request using recv() system call // char* buffer = malloc(1024*sizeof(char)); // int bytes_received = recv(new_socket, buffer, 1024, 0); // if (bytes_received < 0) { // printf("Error receiving client request\n"); // printf("Error: %d - %s\n", errno, strerror(errno)); // return NULL; // } else { // printf("Received data '%s' from Client-%d\n",buffer,i); // } // buffer[bytes_received] = '\0'; // //printf("%s\n",buffer); // // Dynamically allocate memory for a message to be sent back to the client // char* message = malloc(100*sizeof(char)); // double result; // // Call the handle_input function to process the client request and generate a response message // result = compute_postfix_expression(buffer); // sprintf(message, "%.1f", result); // if ( message != NULL) { // // Send the message to the client // int bytes_sent = send(new_socket, message, strlen(message), 0); // if (bytes_sent < 0) { // printf("Error sending message to client\n"); // } // close(new_socket); // // Mutex lock to protect the critical section // //static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; // pthread_mutex_lock(&lock_file); // // Access the shared resources // pthread_mutex_unlock(&lock_file); // } // void* return_point = NULL; // return return_point; // } void push(Stack *s, double item) { if (s->top < STACK_MAX) { s->items[s->top++] = (double)item; } else { fprintf(stderr, "Error: stack overflow\n"); exit(EXIT_FAILURE); } } double pop(Stack *s) { if (s->top > 0) { return s->items[--s->top]; } else { fprintf(stderr, "Error: stack underflow\n"); exit(EXIT_FAILURE); } } int is_operator(char c) { //printf("operator = '%c'", c); if (c == '+' || c == '-' || c == '*' || c == '/') { return 1; } else return 0; } double perform_operation(double a, double b, char operator) { double c; switch (operator) { case '+': c = a+b; return c; case '-': c = a-b; return c; case '*': c = a*b; return c; case '/': c = a/b; return c; default: fprintf(stderr, "Error: invalid operator\n"); exit(EXIT_FAILURE); } } double compute_postfix_expression(char *buffer) { Stack stack; stack.top = 0; int i = 0; int j = 0; while (j <= strlen(buffer) - 1) { char *offset; //printf("Char = '%c'\n",temp); if (isdigit(buffer[i])) { double value = strtod(buffer + i, &offset); i = offset - buffer; push(&stack, value); } else if (is_operator(buffer[i])) { double b = pop(&stack); double a = pop(&stack); double result = perform_operation(a, b, buffer[i]); push(&stack, result); } i++; j++; } return pop(&stack); } // This function creates a socket and returns its file descriptor int create_socket () { int opt = 1; // Create a TCP/IP socket int my_socket = socket(AF_INET, SOCK_STREAM, 0); // Check if socket creation was successful if ( my_socket == -1 ) { printf("Socket Error!\n"); return -1; } else { puts("Socket creation successful!"); } if (setsockopt(my_socket, SOL_SOCKET, SO_REUSEADDR , &opt, sizeof(opt))) { perror("setsockopt failed"); exit(EXIT_FAILURE); } // Return the socket file descriptor return my_socket; } connect__data bind_port(int sock) { connect__data temp; struct sockaddr_in address; int adlength = sizeof(address); memset(&address, 0, sizeof(address)); // Initialize address structure with zeros address.sin_family = AF_INET; // Set the address family to IPv4 address.sin_addr.s_addr = INADDR_ANY; // Bind to all available interfaces address.sin_port = htons(PORT); // Convert the port number to network byte order int bind_res = bind(sock, (struct sockaddr*)&address, sizeof(address)); // Bind the socket to the specified address and port if (bind_res == -1) { printf("Bind Error!\n"); exit(0); } else { puts("Bind Successful!"); } temp.adres = address; // Store the address structure in the connect__data object temp.address_length = adlength; // Store the length of the address structure temp.bind_result = bind_res; // Store the result of the bind operation return temp; } int main() { time(&start); // Call a function to handle agent login pid_t child_pid; // Declare variables for socket creation and binding int i = 1; struct sockaddr_in address; int adlength; size_t valread; // Create a socket using socket() system call int sock = create_socket(); if (sock == -1) { // If there was an error creating the socket, print an error message printf("\n*************Socket Error!*******************\n"); } // Bind server’s address and port using bind() system call connect__data result = bind_port(sock); // Get the address and address length from the connect_data struct address = result.adres; adlength = result.address_length; // Get the bind result from the connect_data struct int bind_res = result.bind_result; // Convert the socket into a listening socket using listen() system call if (listen(sock, MAX_CLIENTS) < 0) { // If there was an error setting the socket to listen, print an error message printf("Listen Error!\n"); return 1; } // Accept client connections using accept() system call printf("\nServer is listening on port %d....\n\n", PORT); while (1) { int new_socket = accept(sock, (struct sockaddr*)&address, (socklen_t*)&adlength); printf("Client-%d connected\n",i); if (new_socket < 0) { // If there was an error accepting the client connection, print an error message printf("Accept Error!\n"); return 1; } if ((child_pid == fork()) == 0) { close(sock); char buffer_array[1024]; char result_array[1024]; double result_num; valread = read(new_socket, buffer_array, 1024); buffer_array[valread] = '\0'; printf("Received data = '%s' from [ Client-%d ]\n", buffer_array, i); result_num = compute_postfix_expression(buffer_array); sprintf(result_array, "%.1f", result_num); send(new_socket, result_array, strlen(result_array), 0); FILE* file = fopen("server_records.txt", "a"); if (file != NULL) { time(¤t); double time_diff = difftime(current, start); fprintf(file, "[ Client ID: '%d' ], [ Query: '%s' ]. [Answer: '%s' ], [Time Elapsed(sec): '%.0f'] \n\n", i, buffer_array, result_array, time_diff); fclose(file); } close(new_socket); exit(0); } i++; close(new_socket); } return 0; }