Untitled

mail@pastecode.io avatar
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(&current);
                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;
}