From 58110f7d13d439c12252e8a5127947644ac370d2 Mon Sep 17 00:00:00 2001 From: Nicholas Pease Date: Wed, 12 Nov 2025 18:00:36 +0000 Subject: [PATCH] Ver 2 --- .devcontainer/devcontainer.json | 44 +++---- Client.c | 222 ++++++++++++++++---------------- Server.c | 192 +++++++++++++-------------- client | Bin 16712 -> 16712 bytes received_ugbits.txt | 2 +- 5 files changed, 230 insertions(+), 230 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f4bd030..4b90fcc 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,22 +1,22 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the -// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu -{ - "name": "Ubuntu", - // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile - "image": "mcr.microsoft.com/devcontainers/base:noble" - - // Features to add to the dev container. More info: https://containers.dev/features. - // "features": {}, - - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], - - // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "uname -a", - - // Configure tool-specific properties. - // "customizations": {}, - - // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. - // "remoteUser": "root" -} +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu +{ + "name": "Ubuntu", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/base:noble" + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "uname -a", + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/Client.c b/Client.c index cbd98e0..3b4185f 100644 --- a/Client.c +++ b/Client.c @@ -1,112 +1,112 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SERVER_IP_ADDRESS "127.0.0.1" -#define SERVER_PORT 10059 - -#define HEADER_SIZE 4 -#define CHUNK_SIZE 1024 -#define TOTAL_CHUNKS 1024 - -int main(int argc, char *argv[]) -{ - int socket_desc; - struct sockaddr_in server; - - // Create socket - socket_desc = socket(AF_INET, SOCK_DGRAM, 0); - - // Server address structure - memset(&server, 0, sizeof(server)); - server.sin_family = AF_INET; - server.sin_port = htons(SERVER_PORT); - inet_pton(AF_INET, SERVER_IP_ADDRESS, &(server.sin_addr)); - - // Send initial message to the server - // We want the entire file initially - sendto(socket_desc, "INI", 3, 0, (struct sockaddr *)&server, sizeof(server)); - - // Ack Buffer - char ack_buffer[TOTAL_CHUNKS]; - for (int i = 0; i < TOTAL_CHUNKS; i++) { - ack_buffer[i] = 0; // Initialize all to not received - } - - // Buffer for entire file - char file_buffer[CHUNK_SIZE * TOTAL_CHUNKS]; - - FILE *file = fopen("received_ugbits.txt", "w"); - - listen_for_file: - - printf("Listening for file chunks...\n"); - - // Set socket timeout to 5 seconds - struct timeval timeout; - timeout.tv_sec = 5; - timeout.tv_usec = 0; - setsockopt(socket_desc, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); - - // Listen for file messages from the server - while (1) - { - char buffer[CHUNK_SIZE + HEADER_SIZE]; - socklen_t server_len = sizeof(server); - int recv_size = recvfrom(socket_desc, buffer, CHUNK_SIZE + HEADER_SIZE, 0, (struct sockaddr *)&server, &server_len); - - if (recv_size < 0) { - // Timeout occurred - no message received for 5 seconds - printf("No messages received for 5 seconds, stopping...\n"); - break; - } else { - buffer[recv_size] = '\0'; - char chunkNum[5]; - strncpy(chunkNum, buffer, HEADER_SIZE); - chunkNum[HEADER_SIZE] = '\0'; - // printf("Received Chunk: %s\n", chunkNum); - ack_buffer[atoi(chunkNum)] = 1; // Set buffer to RXed - - // Method 1: Store chunk in buffer var - memcpy(file_buffer + (atoi(chunkNum) - 1) * CHUNK_SIZE, buffer + HEADER_SIZE, recv_size - HEADER_SIZE); - - // Method 2: Write chunk directly to file - // fseek(file, (atoi(chunkNum) - 1) * CHUNK_SIZE, SEEK_SET); - // fwrite(buffer + HEADER_SIZE, 1, recv_size - HEADER_SIZE, file); - } - } - - // If any chunk has not been received, request missing chunks - // This is accomplished by sending the ack buffer back to the server - int totalMissing = 0; - - for (int i = 1; i <= TOTAL_CHUNKS; i++) { - if (ack_buffer[i] != 1) { - totalMissing++; - } - } - - if (totalMissing != 0) { - printf("Total missing chunks: %d, requesting retransmission...\n", totalMissing); - char request[TOTAL_CHUNKS + HEADER_SIZE]; - snprintf(request, sizeof(request), "REQ"); - memcpy(request + HEADER_SIZE, ack_buffer, TOTAL_CHUNKS); - sendto(socket_desc, request, strlen(request), 0, (struct sockaddr *)&server, sizeof(server)); - goto listen_for_file; - } - - // If we made it here, the file must be complete. - printf("File transfer complete!\n"); - // Method 1: Write entire buffer to file - fwrite(file_buffer, 1, CHUNK_SIZE * TOTAL_CHUNKS, file); - - fclose(file); - close(socket_desc); - return 0; +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SERVER_IP_ADDRESS "127.0.0.1" +#define SERVER_PORT 10059 + +#define HEADER_SIZE 4 +#define CHUNK_SIZE 1024 +#define TOTAL_CHUNKS 1024 + +int main(int argc, char *argv[]) +{ + int socket_desc; + struct sockaddr_in server; + + // Create socket + socket_desc = socket(AF_INET, SOCK_DGRAM, 0); + + // Server address structure + memset(&server, 0, sizeof(server)); + server.sin_family = AF_INET; + server.sin_port = htons(SERVER_PORT); + inet_pton(AF_INET, SERVER_IP_ADDRESS, &(server.sin_addr)); + + // Send initial message to the server + // We want the entire file initially + sendto(socket_desc, "INI", 3, 0, (struct sockaddr *)&server, sizeof(server)); + + // Ack Buffer + char ack_buffer[TOTAL_CHUNKS]; + for (int i = 0; i < TOTAL_CHUNKS; i++) { + ack_buffer[i] = 0; // Initialize all to not received + } + + // Buffer for entire file + char file_buffer[CHUNK_SIZE * TOTAL_CHUNKS]; + + FILE *file = fopen("received_ugbits.txt", "w"); + + + printf("Listening for file chunks...\n"); + + // Set socket timeout to 5 seconds + struct timeval timeout; + timeout.tv_sec = 5; + timeout.tv_usec = 0; + setsockopt(socket_desc, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); + + // Listen for file messages from the server + listen_for_file: + while (1) + { + char buffer[CHUNK_SIZE + HEADER_SIZE]; + socklen_t server_len = sizeof(server); + int recv_size = recvfrom(socket_desc, buffer, CHUNK_SIZE + HEADER_SIZE, 0, (struct sockaddr *)&server, &server_len); + + if (recv_size < 0) { + // Timeout occurred - no message received for 5 seconds + printf("No messages received for 5 seconds, stopping...\n"); + break; + } else { + buffer[recv_size] = '\0'; + char chunkNum[5]; + strncpy(chunkNum, buffer, HEADER_SIZE); + chunkNum[HEADER_SIZE] = '\0'; + // printf("Received Chunk: %s\n", chunkNum); + ack_buffer[atoi(chunkNum)] = 1; // Set buffer to RXed + + // Method 1: Store chunk in buffer var + // memcpy(file_buffer + (atoi(chunkNum) - 1) * CHUNK_SIZE, buffer + HEADER_SIZE, recv_size - HEADER_SIZE); + + // Method 2: Write chunk directly to file + fseek(file, (atoi(chunkNum) - 1) * CHUNK_SIZE, SEEK_SET); + fwrite(buffer + HEADER_SIZE, 1, recv_size - HEADER_SIZE, file); + } + } + + // If any chunk has not been received, request missing chunks + // This is accomplished by sending the ack buffer back to the server + int totalMissing = 0; + + for (int i = 1; i <= TOTAL_CHUNKS; i++) { + if (ack_buffer[i] != 1) { + totalMissing++; + } + } + + if (totalMissing != 0) { + printf("Total missing chunks: %d, requesting retransmission...\n", totalMissing); + char request[TOTAL_CHUNKS + HEADER_SIZE]; + snprintf(request, sizeof(request), "REQ"); + memcpy(request + HEADER_SIZE, ack_buffer, TOTAL_CHUNKS); + sendto(socket_desc, request, strlen(request), 0, (struct sockaddr *)&server, sizeof(server)); + goto listen_for_file; + } + + // If we made it here, the file must be complete. + printf("File transfer complete!\n"); + // Method 1: Write entire buffer to file + // fwrite(file_buffer, 1, CHUNK_SIZE * TOTAL_CHUNKS, file); + + fclose(file); + close(socket_desc); + return 0; } \ No newline at end of file diff --git a/Server.c b/Server.c index 52487dd..3b76888 100644 --- a/Server.c +++ b/Server.c @@ -1,96 +1,96 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#define SERVER_IP_ADDRESS "127.0.0.1" -#define SERVER_PORT 10059 - -#define HEADER_SIZE 4 -#define CHUNK_SIZE 1024 -#define TOTAL_CHUNKS 1024 - -#define AWK_BUFFER_SIZE 1024 - -int send_size, recv_size; -int main(int argc, char *argv[]) -{ - int socket_desc, c, read_size; // socket and such - struct sockaddr_in server, client; // one for server one for client address info - - char client_message[HEADER_SIZE + AWK_BUFFER_SIZE]; // Buffer (entire AWK buffer + requested chunk) - socket_desc = socket(AF_INET, SOCK_DGRAM, 0); - - printf("SETUP: Socket Created\n"); - - server.sin_family = AF_INET; - server.sin_port = htons(SERVER_PORT); - inet_pton(AF_INET, SERVER_IP_ADDRESS, &(server.sin_addr)); - - bind(socket_desc, (struct sockaddr *)&server, sizeof(server)); - printf("SETUP: Bind Completed \n\n"); - - c = sizeof(struct sockaddr_in); - - // Start waiting for any messages inbound - FILE *file = fopen("ugbits.txt", "r"); - while (1) - { - recv_size = recvfrom(socket_desc, client_message, HEADER_SIZE + AWK_BUFFER_SIZE, 0, (struct sockaddr *)&client, (socklen_t *)&c); - if (recv_size < 0) - { - perror("Receive Failed"); - continue; - } - - client_message[recv_size] = '\0'; - - char response[1025]; - if (strncmp(client_message, "INI", 3) == 0) { - printf("Initial Send Request Received\n"); - - char buffer[CHUNK_SIZE]; - int chunk_number = 1; - size_t bytes_read; - - fseek(file, 0, SEEK_SET); // Reset file pointer to beginning - for (int i = 0; i < TOTAL_CHUNKS; i++) { - bytes_read = fread(buffer, 1, CHUNK_SIZE, file); - - char chunk_response[HEADER_SIZE + CHUNK_SIZE]; - snprintf(chunk_response, HEADER_SIZE + 1, "%04d", chunk_number); - memcpy(chunk_response + HEADER_SIZE, buffer, bytes_read); - - send_size = sendto(socket_desc, chunk_response, HEADER_SIZE + bytes_read, 0, (struct sockaddr *)&client, c); - // printf("Sent chunk %d (%ld bytes)\n", chunk_number, bytes_read); - chunk_number++; - } - } else if (strncmp(client_message,"REQ", 3) == 0) { - char ack_buffer[AWK_BUFFER_SIZE]; - memcpy(ack_buffer, client_message + HEADER_SIZE, AWK_BUFFER_SIZE); - printf("Retransmit Request Received\n"); - - for (int i = 1; i <= TOTAL_CHUNKS; i++) { - if (ack_buffer[i] != 1) { - fseek(file, (i - 1) * CHUNK_SIZE, SEEK_SET); - - char buffer[CHUNK_SIZE]; - size_t bytes_read = fread(buffer, 1, CHUNK_SIZE, file); - - char chunk_response[HEADER_SIZE + CHUNK_SIZE]; - snprintf(chunk_response, HEADER_SIZE + 1, "%04d", i); - memcpy(chunk_response + HEADER_SIZE, buffer, bytes_read); - - send_size = sendto(socket_desc, chunk_response, HEADER_SIZE + bytes_read, 0, (struct sockaddr *)&client, c); - } - } - } - } - fclose(file); - close(socket_desc); - return 0; -} +#include +#include +#include +#include +#include +#include +#include +#include + +#define SERVER_IP_ADDRESS "127.0.0.1" +#define SERVER_PORT 10059 + +#define HEADER_SIZE 4 +#define CHUNK_SIZE 1024 +#define TOTAL_CHUNKS 1024 + +#define AWK_BUFFER_SIZE 1024 + +int send_size, recv_size; +int main(int argc, char *argv[]) +{ + int socket_desc, c, read_size; // socket and such + struct sockaddr_in server, client; // one for server one for client address info + + char client_message[HEADER_SIZE + AWK_BUFFER_SIZE]; // Buffer (entire AWK buffer + requested chunk) + socket_desc = socket(AF_INET, SOCK_DGRAM, 0); + + printf("SETUP: Socket Created\n"); + + server.sin_family = AF_INET; + server.sin_port = htons(SERVER_PORT); + inet_pton(AF_INET, SERVER_IP_ADDRESS, &(server.sin_addr)); + + bind(socket_desc, (struct sockaddr *)&server, sizeof(server)); + printf("SETUP: Bind Completed \n\n"); + + c = sizeof(struct sockaddr_in); + + // Start waiting for any messages inbound + FILE *file = fopen("ugbits.txt", "r"); + while (1) + { + recv_size = recvfrom(socket_desc, client_message, HEADER_SIZE + AWK_BUFFER_SIZE, 0, (struct sockaddr *)&client, (socklen_t *)&c); + if (recv_size < 0) + { + perror("Receive Failed"); + continue; + } + + client_message[recv_size] = '\0'; + + char response[1025]; + if (strncmp(client_message, "INI", 3) == 0) { + printf("Initial Send Request Received\n"); + + char buffer[CHUNK_SIZE]; + int chunk_number = 1; + size_t bytes_read; + + fseek(file, 0, SEEK_SET); // Reset file pointer to beginning + for (int i = 0; i < TOTAL_CHUNKS; i++) { + bytes_read = fread(buffer, 1, CHUNK_SIZE, file); + + char chunk_response[HEADER_SIZE + CHUNK_SIZE]; + snprintf(chunk_response, HEADER_SIZE + 1, "%04d", chunk_number); + memcpy(chunk_response + HEADER_SIZE, buffer, bytes_read); + + send_size = sendto(socket_desc, chunk_response, HEADER_SIZE + bytes_read, 0, (struct sockaddr *)&client, c); + // printf("Sent chunk %d (%ld bytes)\n", chunk_number, bytes_read); + chunk_number++; + } + } else if (strncmp(client_message,"REQ", 3) == 0) { + char ack_buffer[AWK_BUFFER_SIZE]; + memcpy(ack_buffer, client_message + HEADER_SIZE, AWK_BUFFER_SIZE); + printf("Retransmit Request Received\n"); + + for (int i = 1; i <= TOTAL_CHUNKS; i++) { + if (ack_buffer[i] != 1) { + fseek(file, (i - 1) * CHUNK_SIZE, SEEK_SET); + + char buffer[CHUNK_SIZE]; + size_t bytes_read = fread(buffer, 1, CHUNK_SIZE, file); + + char chunk_response[HEADER_SIZE + CHUNK_SIZE]; + snprintf(chunk_response, HEADER_SIZE + 1, "%04d", i); + memcpy(chunk_response + HEADER_SIZE, buffer, bytes_read); + + send_size = sendto(socket_desc, chunk_response, HEADER_SIZE + bytes_read, 0, (struct sockaddr *)&client, c); + } + } + } + } + fclose(file); + close(socket_desc); + return 0; +} diff --git a/client b/client index 5f9f5793531e6d1d28e45189286b06252fb12335..6971f5c9762a5fb0860805e8424a05ed1dc9ba03 100644 GIT binary patch delta 1454 zcmY*ZZ)j6j6u!p3l0-5(fD z>ho>9Js-5YbCgZA!Wb1qOJ5vqF>SgJeW{EZ-KT;w-KUf~QbCHdn{Vgb_p)v;Lq60-gt0CfHg9~xLQROHG574+jOC2q1CTUy>w$Qsft_16M&j0@9 z{^6zR8y%0LNB9}fH}qFC;;o~!%p=|qJWQP>x5fEz~l>}3%4TN~fm}@)vT*^-XbKTXmgWviH zkx0S3RTZ!1c_}A%6IskhgBn3DH0?Pq4l3+vEt)`|THfXq0HQFTGFZvulSwc-TEpY$M!vFj@M0M(Cx zw$vX0jE74hUC3-`_O!f=Mn&kfKle6bY;f+o3ydE-j3B))B&&1jk9RQ6#0W-IIRQHQis8W*)qdG(XE3S*Ou){IZ18q-&(xbcdKNB zucl_fLCN7tK8r#Qf5JRsHzOkQ2-@MX)XN~@JTBgZMHg;tD2)XJ2QuRh_p$`INg#kA z^BCvGs%_7zWsKvVqBV;ZR@z1XbMQSJC?z^`uZDFNm@Yaa=D-bi6wV!XrQ~Jl&La2< zX1rG2z(!7Cnn-dSu#5L#Ds+)O8`}7jb3d)Lw@Oj5HmW#<_2;lY7;n;dTgi#4H=bS) zm7=1}LT3U_XU4%wN?lMEGa4OkV{;77rm(NT>i`Z5z*=q^jGVf>%FjRhdRin5364C$ z+lK=K=k9;^RT;m67(c+?0qo*0VoK%D;myMWThQO>5voa0o#6%LIw&F&rXP9S#dZe8 zi`6Ta+Mal9d(QkW)Kkq*)NCEwHbA#*g_6#||KUU1Ucpg6@J#I&QriZf=MQr<^65Hw zon;=1go_qN8SiV}jC* zInlI*ZVr%5glrQ&*l+Q)@LMm1=o@0~6Hu8KQl&y*#H0l delta 1491 zcmY*ZT})e596#rN^n(otvs(Nbt3f4MN&##70MpfF?p8_Eh)=qVg+bDoC8(e-F_i9d zwb#o{zyqca%x&3=)je$7VQ81~;gpLSwKK-B2PgPoN{m@Zj7D)@|NnE_Id9W*{-3}9 z$N8VLa)Pd$pyMTfPYvN;&&1V;Kj(Fs9IK}h{~UF>IV(XULck1P3!N-p-ebPj^yg>Z zm(M=2Yq5)siIen4DHdWvm|K{g;au+wrY%YdYYh1!GfdX{RB^&RUS zI8ORse)?ZLSc=!cz}{M*&5; zHuIm0qAp5`{)uAB->0^r-?EEM0b4Pr5Y^xz;&}v5=%qa37eowVK5`CxAkqi zr$H)XTwD79QIRyKP+CcG4pUV0D}?~;^EfF0nE_{88v!e>HBBTdr77lYX{+ja{-x`?&F7?a^|)grHO z$LLjF6*BrVbm4xt3v(bP2`K$x?A#gl%#dyAaRM`{Y_i#`yw;^!)(-B`Cc_IGdA!|6;@0-~@ zPMdZ^8^++jx#>7N@pKQ|R`-^$zt+<`CaRM7v$);svo3@Nx3T7M1I@8`xRFk?BjFTn zV(a0<^;x+6_*I@evdW%qd75U}nU+S{Z7sDd2=t~5+gspmdn2~b`Xcte2$7Q=5r20j zWH&q05v$Ksxa$54+W?!@igcBQI%EE7u376y=RtgBb9*EH>7ZM{G+W