// server_udp_third.c #include #include #include #include #include #include #include #include #define BUF_SIZE 4096 #define END_MARKER "END_OF_TRANSMISSION" static void process_block(char *buf, ssize_t len, long long *pos_counter, long long *repl_counter) { if (!buf || !pos_counter || !repl_counter) { return; } for (ssize_t i = 0; i < len; i++) { char c = buf[i]; long long pos = *pos_counter; if (((pos + 1) % 3 == 0) && c != '\0') { buf[i] = ' '; (*repl_counter)++; } (*pos_counter)++; } } int main(int argc, char *argv[]) { if (argc < 3) { fprintf(stderr, "Usage: %s \n", argv[0]); fprintf(stderr, "Example: %s 5000 out.txt\n", argv[0]); return -1; } char *endptr = NULL; errno = 0; long port_long = strtol(argv[1], &endptr, 10); if (errno != 0 || endptr == argv[1] || *endptr != '\0' || port_long <= 0 || port_long > 65535) { fprintf(stderr, "ERROR: invalid port '%s'\n", argv[1]); return -1; } int port = (int) port_long; const char *out_path = argv[2]; FILE *fout = fopen(out_path, "w"); if (!fout) { perror("fopen(output_file)"); return -1; } int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { perror("socket"); fclose(fout); return -1; } struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(port); if (bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) { perror("bind"); close(sockfd); fclose(fout); return -1; } printf("UDP server (third-char) listening on port %d, output file: %s\n", port, out_path); char buf[BUF_SIZE]; long long pos_counter = 0; long long repl_counter = 0; int done = 0; while (!done) { struct sockaddr_in cliaddr; socklen_t cli_len = sizeof(cliaddr); ssize_t n = recvfrom(sockfd, buf, sizeof(buf) - 1, 0, (struct sockaddr *) &cliaddr, &cli_len); if (n < 0) { perror("recvfrom"); repl_counter = -1; break; } buf[n] = '\0'; if (strcmp(buf, END_MARKER) == 0) { printf("Received END marker from %s:%d, finishing.\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port)); done = 1; break; } process_block(buf, n, &pos_counter, &repl_counter); if (fwrite(buf, 1, (size_t) n, fout) != (size_t) n) { perror("fwrite"); repl_counter = -1; done = 1; break; } } if (fclose(fout) == EOF) { perror("fclose(output_file)"); repl_counter = -1; } close(sockfd); printf("Total replacements (every 3rd char): %lld\n", repl_counter); if (repl_counter < 0) { return -1; } return 0; }