aboutsummaryrefslogtreecommitdiff
path: root/pa1_file_transfer/uftp_client.c
diff options
context:
space:
mode:
authorJack Sangdahl <[email protected]>2024-10-02 12:58:44 -0600
committerJack Sangdahl <[email protected]>2024-10-02 12:58:44 -0600
commitbba288a79171b2f3cf7efb72e56c0c6fb5cf6116 (patch)
treef3c8f96894097394685dd228b57c8b25a2ae54b5 /pa1_file_transfer/uftp_client.c
parentfa8c37bb3ecd3cc6caba9b6bf465c360301432ea (diff)
downloadecen5273-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.c157
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;
+}