uftp_client.c (6237B)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 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; } |