Final Project Simple File Server
For your final project, you will create a simple file server and client in C. This project will bring together the networking concepts you have learned so far, including sockets, protocol design, and file transfer. The server will serve files from a specified directory. When a client connects, the server will send a list of available files. The client can request a file by name, and the server will send the file's contents back for the client to save locally.
Your project requirements are as follows:
- The server must listen for incoming connections on a specified port;
- When a client connects, the server must send a list of available files in its directory;
- The client must display this list and allow the user to select a file to download;
- The client sends the file name to the server, which then sends the file's contents;
- The client saves the received file locally;
- Both server and client should handle errors, such as file not found or connection issues.
The design plan is straightforward:
- Start the server, which scans its directory for files and waits for a client connection;
- When a client connects, send the list of files, separated by newlines;
- The client receives and displays this list, then prompts the user for a filename;
- The client sends the filename to the server;
- The server checks if the file exists. If yes, it sends the file size, then the file contents. If not, it sends an error message;
- The client receives the file (or error message) and saves it, displaying appropriate messages for success or failure.
This step-by-step plan ensures a clear protocol and robust error handling, while reinforcing your understanding of sockets, file I/O, and communication patterns.
server.c
client.c
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109#include <stdio.h> #include <stdlib.h> #include <string.h> #include <dirent.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/stat.h> #include <errno.h> #define PORT 9000 #define BUF_SIZE 1024 #define FILE_DIR "./files" void send_file_list(int client_sock) { DIR *d; struct dirent *dir; char list[BUF_SIZE] = ""; d = opendir(FILE_DIR); if (d) { while ((dir = readdir(d)) != NULL) { if (dir->d_type == DT_REG) { strcat(list, dir->d_name); strcat(list, "\n"); } } closedir(d); } send(client_sock, list, strlen(list), 0); } void send_file(int client_sock, const char *filename) { char filepath[512]; snprintf(filepath, sizeof(filepath), "%s/%s", FILE_DIR, filename); FILE *fp = fopen(filepath, "rb"); if (!fp) { char *err = "ERROR: File not found\n"; send(client_sock, err, strlen(err), 0); return; } fseek(fp, 0, SEEK_END); long filesize = ftell(fp); fseek(fp, 0, SEEK_SET); char header[64]; snprintf(header, sizeof(header), "OK %ld\n", filesize); send(client_sock, header, strlen(header), 0); char buf[BUF_SIZE]; size_t n; while ((n = fread(buf, 1, BUF_SIZE, fp)) > 0) { if (send(client_sock, buf, n, 0) != n) { break; } } fclose(fp); } int main() { int server_fd, client_sock; struct sockaddr_in server_addr, client_addr; socklen_t addr_len = sizeof(client_addr); mkdir(FILE_DIR, 0777); // ensure directory exists server_fd = socket(AF_INET, SOCK_STREAM, 0); if (server_fd < 0) { perror("socket"); exit(1); } server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(PORT); if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("bind"); close(server_fd); exit(1); } if (listen(server_fd, 5) < 0) { perror("listen"); close(server_fd); exit(1); } printf("File server listening on port %d...\n", PORT); while (1) { client_sock = accept(server_fd, (struct sockaddr *)&client_addr, &addr_len); if (client_sock < 0) { perror("accept"); continue; } printf("Client connected: %s\n", inet_ntoa(client_addr.sin_addr)); send_file_list(client_sock); char filename[256] = {0}; int len = recv(client_sock, filename, sizeof(filename) - 1, 0); if (len > 0) { filename[strcspn(filename, "\r\n")] = 0; // remove newline send_file(client_sock, filename); } close(client_sock); printf("Client disconnected.\n"); } close(server_fd); return 0; }
Grazie per i tuoi commenti!
Chieda ad AI
Chieda ad AI
Chieda pure quello che desidera o provi una delle domande suggerite per iniziare la nostra conversazione
Fantastico!
Completion tasso migliorato a 8.33
Final Project Simple File Server
Scorri per mostrare il menu
For your final project, you will create a simple file server and client in C. This project will bring together the networking concepts you have learned so far, including sockets, protocol design, and file transfer. The server will serve files from a specified directory. When a client connects, the server will send a list of available files. The client can request a file by name, and the server will send the file's contents back for the client to save locally.
Your project requirements are as follows:
- The server must listen for incoming connections on a specified port;
- When a client connects, the server must send a list of available files in its directory;
- The client must display this list and allow the user to select a file to download;
- The client sends the file name to the server, which then sends the file's contents;
- The client saves the received file locally;
- Both server and client should handle errors, such as file not found or connection issues.
The design plan is straightforward:
- Start the server, which scans its directory for files and waits for a client connection;
- When a client connects, send the list of files, separated by newlines;
- The client receives and displays this list, then prompts the user for a filename;
- The client sends the filename to the server;
- The server checks if the file exists. If yes, it sends the file size, then the file contents. If not, it sends an error message;
- The client receives the file (or error message) and saves it, displaying appropriate messages for success or failure.
This step-by-step plan ensures a clear protocol and robust error handling, while reinforcing your understanding of sockets, file I/O, and communication patterns.
server.c
client.c
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109#include <stdio.h> #include <stdlib.h> #include <string.h> #include <dirent.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/stat.h> #include <errno.h> #define PORT 9000 #define BUF_SIZE 1024 #define FILE_DIR "./files" void send_file_list(int client_sock) { DIR *d; struct dirent *dir; char list[BUF_SIZE] = ""; d = opendir(FILE_DIR); if (d) { while ((dir = readdir(d)) != NULL) { if (dir->d_type == DT_REG) { strcat(list, dir->d_name); strcat(list, "\n"); } } closedir(d); } send(client_sock, list, strlen(list), 0); } void send_file(int client_sock, const char *filename) { char filepath[512]; snprintf(filepath, sizeof(filepath), "%s/%s", FILE_DIR, filename); FILE *fp = fopen(filepath, "rb"); if (!fp) { char *err = "ERROR: File not found\n"; send(client_sock, err, strlen(err), 0); return; } fseek(fp, 0, SEEK_END); long filesize = ftell(fp); fseek(fp, 0, SEEK_SET); char header[64]; snprintf(header, sizeof(header), "OK %ld\n", filesize); send(client_sock, header, strlen(header), 0); char buf[BUF_SIZE]; size_t n; while ((n = fread(buf, 1, BUF_SIZE, fp)) > 0) { if (send(client_sock, buf, n, 0) != n) { break; } } fclose(fp); } int main() { int server_fd, client_sock; struct sockaddr_in server_addr, client_addr; socklen_t addr_len = sizeof(client_addr); mkdir(FILE_DIR, 0777); // ensure directory exists server_fd = socket(AF_INET, SOCK_STREAM, 0); if (server_fd < 0) { perror("socket"); exit(1); } server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(PORT); if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("bind"); close(server_fd); exit(1); } if (listen(server_fd, 5) < 0) { perror("listen"); close(server_fd); exit(1); } printf("File server listening on port %d...\n", PORT); while (1) { client_sock = accept(server_fd, (struct sockaddr *)&client_addr, &addr_len); if (client_sock < 0) { perror("accept"); continue; } printf("Client connected: %s\n", inet_ntoa(client_addr.sin_addr)); send_file_list(client_sock); char filename[256] = {0}; int len = recv(client_sock, filename, sizeof(filename) - 1, 0); if (len > 0) { filename[strcspn(filename, "\r\n")] = 0; // remove newline send_file(client_sock, filename); } close(client_sock); printf("Client disconnected.\n"); } close(server_fd); return 0; }
Grazie per i tuoi commenti!