Creating a client-server system with basic file operations like upload and download

Viewed 25

I am trying to create a basic single-threaded client-server system where the client can upload, download files to and from the server. Now I have figured out how to download and upload files, but I can do them as separate standalone programs. I am trying to do this by a switch case where the client will be able to choose the options, and then do the function accordingly.

My client side code is:

void send_file(FILE *fp, int sockfd)
{
    int n;
    char data[BUFFER] = {0};

    while(fgets(data, BUFFER, fp) != NULL) 
    {
        if (send(sockfd, data, sizeof(data), 0) == -1) 
        {
            perror("[-]Error in sending file.");
            exit(1);
        }
    bzero(data, BUFFER);
}
int main()
{
    char *ip = "127.0.0.1";
    int port = 8080;

    int sock, n, user_choice;
    struct sockaddr_in addr;
    socklen_t addr_size;
    char buffer[BUFFER];
    FILE *fp;
    char file[50];
    char *filename;

    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0)
    {
        perror("[-]Socket error");
        exit(1);
    }
    printf("[+]Socket created\n");

    memset(&addr, '\0', sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = port;
    addr.sin_addr.s_addr = inet_addr(ip);

    connect(sock, (struct sockaddr *)&addr, sizeof(addr));
    printf("Connected to the server\n");

    //once the client is connected to server, I am presenting the options

    printf("What do you want to do?\n1.Upload a file\n2.Download a file\n");
    scanf("%d", &user_choice);
    switch(user_choice)
    {
        case 1:
             printf("Input name of file to be uploaded:\n");
             scanf("%s", file);
             filename = file;
             fp = fopen(filename, "r");
             if (fp == NULL)
             {
                 perror("[-]Error in reading file.");
                 exit(1);
             }
             send_file(fp, sock);
             printf("[+]File data sent successfully.\n");
    
        case 2:
             write(sock, &user_choice, sizeof(user_choice));
     }
return 0;
}

My server side code is:

void write_file(int sock)
{
    int n;
    FILE *fp;
    char *filename = "recv.txt";
    char buffer[BUFFER];
    
    fp = fopen(filename, "w"); 
    while (1) 
    {
        n = recv(sock, buffer, BUFFER, 0);
        if (n <= 0)
        {
           break;
           return;
        }
        fprintf(fp, "%s", buffer);
        bzero(buffer, BUFFER);
     }
 return;
}
int main()
{
    char *ip = "127.0.0.1";
    int port = 8080;

    int server_sock, client_sock;
    struct sockaddr_in server_addr, client_addr;
    socklen_t addr_size;
    char buffer[BUFFER];
    int n, user_choice;

    server_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (server_sock < 0)
    {
       perror("[-]Socket error");
       exit(1);
    }
    printf("[+]Socket created\n");

    memset(&server_addr, '\0', sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = port;
    server_addr.sin_addr.s_addr = inet_addr(ip);

    n = bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (n < 0)
    {
        perror("[-]Bind error");
        exit(1);
    }
    printf("[+]Bind successful\n");

    listen(server_sock, 5);
    printf("Listening...\n");

    while(1)
    {
        addr_size = sizeof(client_addr);
        client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &addr_size);
        printf("[+]Client connected\n");

        read(client_sock, &user_choice, sizeof(user_choice));
    
        switch(user_choice)
        {
           case 1:
               printf("User chose upload option\n");
               write_file(client_sock);
               printf("[+]File uploaded successfully.\n");
           case 2:
               printf("User chose download option\n"); //if the switch worked, then I want to create other functions from here and execute accordingly.
        }
    }
    close(client_sock);
    printf("[+]Client disconnected.\n");

    return 0;
}

My question is: How do I implement the switch cases such that when the client chooses an option on their side, the server will know what the client has chosen and behave accordingly?

0 Answers
Related