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?