diff options
author | Jack Sangdahl <[email protected]> | 2024-10-02 12:58:44 -0600 |
---|---|---|
committer | Jack Sangdahl <[email protected]> | 2024-10-02 12:58:44 -0600 |
commit | bba288a79171b2f3cf7efb72e56c0c6fb5cf6116 (patch) | |
tree | f3c8f96894097394685dd228b57c8b25a2ae54b5 /pa1_file_transfer/uftp_client.c | |
parent | fa8c37bb3ecd3cc6caba9b6bf465c360301432ea (diff) | |
download | ecen5273-bba288a79171b2f3cf7efb72e56c0c6fb5cf6116.tar.gz ecen5273-bba288a79171b2f3cf7efb72e56c0c6fb5cf6116.zip |
Programming Assignment 1: File Transfer
Signed-off-by: Jack Sangdahl <[email protected]>
Diffstat (limited to 'pa1_file_transfer/uftp_client.c')
-rw-r--r-- | pa1_file_transfer/uftp_client.c | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/pa1_file_transfer/uftp_client.c b/pa1_file_transfer/uftp_client.c new file mode 100644 index 0000000..6e1adb6 --- /dev/null +++ b/pa1_file_transfer/uftp_client.c @@ -0,0 +1,157 @@ +// File Transfer (Client) +// Jack Sangdahl +// 07 September 2024 +#include <fcntl.h> +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <unistd.h> + +#define DATA_SIZE 1024 + +int main(int argc, char **argv) { + if (argc != 3) { + fprintf(stderr, "usage: %s <ip_addr> <port_num>\n", argv[0]); + exit(EXIT_FAILURE); + } + char *hostname = argv[1]; + int port = atoi(argv[2]), sock; + if (port > 65535 || port < 5000) { + fprintf(stderr, "%s: port must be in range 5000-65535\n", argv[0]); + exit(EXIT_FAILURE); + } + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + fprintf(stderr, "%s: error opening socket\n", argv[0]); + exit(EXIT_FAILURE); + } + struct hostent *server = gethostbyname(hostname); + if (!server) { + fprintf(stderr, "%s: error determining server\n", argv[0]); + exit(EXIT_FAILURE); + } + struct sockaddr_in server_addr; + memset(&server_addr, 0, sizeof(server_addr)); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(port); + server_addr.sin_addr.s_addr = INADDR_ANY; + memcpy((char *)&server_addr.sin_addr.s_addr, (char *)server->h_addr, + server->h_length); + socklen_t server_size = sizeof(server_addr); + char data[DATA_SIZE], command[DATA_SIZE], filename[DATA_SIZE]; + while (1) { + memset(data, 0, strlen(data)); + printf("usage: get [filename] | put [filename] | delete [filename] | ls | " + "exit\n"); + fgets(data, DATA_SIZE, stdin); + data[strcspn(data, "\n")] = 0; + sscanf(data, "%s %s", command, filename); + if (!strncmp(command, "get", 3)) { + if (sendto(sock, data, strlen(data), 0, (struct sockaddr *)&server_addr, + server_size) < 0) + fprintf(stderr, "%s: error sending data to server\n", argv[0]); + int rec_data; + if (recvfrom(sock, &rec_data, sizeof(rec_data), 0, + (struct sockaddr *)&server_addr, &server_size) < 0) + fprintf(stderr, "%s: error receiving status from server\n", argv[0]); + if (rec_data == -1) { + fprintf(stderr, "error: file %s does not exist on server\n", filename); + continue; + } + if (recvfrom(sock, data, sizeof(data), 0, (struct sockaddr *)&server_addr, + &server_size) < 0) + fprintf(stderr, "%s: error receiving file size\n", argv[0]); + int file_size = atoi(data); + printf("receiving file %s/%d bytes from server...\n", filename, + file_size); + int f = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666); + int bytes_transferred = 0; + while (bytes_transferred < file_size) { + memset(data, 0, sizeof(data)); + ssize_t received = + recvfrom(sock, data, sizeof(data), 0, + (struct sockaddr *)&server_addr, &server_size); + if (received < 0) + fprintf(stderr, "%s: error receiving file data\n", argv[0]); + write(f, data, received); + bytes_transferred += received; + printf("received %d/%d bytes\n", bytes_transferred, file_size); + } + close(f); + printf("file transferred successfully.\n"); + } else if (!strncmp(command, "put", 3)) { + printf("sending file %s to server...\n", filename); + int f = open(filename, O_RDONLY); + if (f < 0) { + fprintf(stderr, "error: file %s does not exist in directory\n", + filename); + continue; + } + if (sendto(sock, data, strlen(data), 0, (struct sockaddr *)&server_addr, + server_size) < 0) + fprintf(stderr, "%s: error sending data to server\n", argv[0]); + off_t file_size = lseek(f, 0, SEEK_END); + lseek(f, 0, SEEK_SET); + char file_data[DATA_SIZE]; + sprintf(file_data, "%ld", (long)file_size); + if (sendto(sock, file_data, DATA_SIZE, 0, (struct sockaddr *)&server_addr, + server_size) < 0) + fprintf(stderr, "%s: error sending file size to server\n", argv[0]); + memset(data, 0, sizeof(data)); + ssize_t bytes_read; + while ((bytes_read = read(f, file_data, sizeof(file_data))) > 0) { + if (sendto(sock, file_data, bytes_read, 0, + (struct sockaddr *)&server_addr, server_size) < 0) { + fprintf(stderr, "%s: error sending data to server\n", argv[0]); + break; + } + memset(file_data, 0, sizeof(file_data)); + } + if (bytes_read < 0) + fprintf(stderr, "error reading file %s\n", filename); + else + printf("file %s transferred successfully\n", filename); + close(f); + + } else if (!strncmp(command, "delete", 6)) { + if (sendto(sock, data, strlen(data), 0, (struct sockaddr *)&server_addr, + server_size) < 0) + fprintf(stderr, "%s: error sending data to server\n", argv[0]); + int rec_data; + if (recvfrom(sock, &rec_data, sizeof(int), 0, + (struct sockaddr *)&server_addr, &server_size) < 0) + fprintf(stderr, "%s: error receiving data from server\n", argv[0]); + switch (rec_data) { + case 0: + printf("file %s deleted successfully\n", filename); + break; + case 1: + printf("file %s does not exist on server\n", filename); + break; + case 2: + printf("error deleting file %s on server\n", filename); + break; + } + } else if (!strncmp(command, "ls", 2)) { + if (sendto(sock, data, strlen(data), 0, (struct sockaddr *)&server_addr, + server_size) < 0) + fprintf(stderr, "%s: error sending data to server\n", argv[0]); + if (recvfrom(sock, data, sizeof(data), 0, (struct sockaddr *)&server_addr, + &server_size) < 0) + fprintf(stderr, "%s: error receiving data from server\n", argv[0]); + printf("%s\n", data); + } else if (!strncmp(command, "exit", 4)) { + if (sendto(sock, data, strlen(data), 0, (struct sockaddr *)&server_addr, + server_size) < 0) + fprintf(stderr, "%s: error sending data to server\n", argv[0]); + if (close(sock) < 0) + fprintf(stderr, "%s: error closing socket\n", argv[0]); + printf("%s: server connection closed\n", argv[0]); + break; + } else + printf("invalid command!\n"); + } + return EXIT_SUCCESS; +} |