// UDP‑клиент: читает файл и отправляет его содержимое серверу блоками UDP. #include #include #include #include #include #include // inet_pton, sockaddr_in #include #include #define BUF_SIZE 4096 #define END_MARKER "END_OF_TRANSMISSION" int main(int argc, char *argv[]) { // argv[1] — IP сервера, argv[2] — порт, argv[3] — входной файл. if (argc < 4) { fprintf(stderr, "Usage: %s \n", argv[0]); fprintf(stderr, "Example: %s 127.0.0.1 5000 in.txt\n", argv[0]); return -1; } const char *server_ip = argv[1]; const char *server_port = argv[2]; const char *input_path = argv[3]; // Разбираем номер порта. char *endptr = NULL; errno = 0; long port_long = strtol(server_port, &endptr, 10); if (errno != 0 || endptr == server_port || *endptr != '\0' || port_long <= 0 || port_long > 65535) { fprintf(stderr, "ERROR: invalid port '%s'\n", server_port); return -1; } int port = (int) port_long; FILE *fin = fopen(input_path, "r"); if (!fin) { perror("fopen(input_file)"); return -1; } // Создаём UDP‑сокет. int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { perror("socket"); fclose(fin); return -1; } // Заполняем адрес сервера: IPv4 + порт. struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(port); // inet_pton конвертирует строку IP ("127.0.0.1") в бинарный вид. if (inet_pton(AF_INET, server_ip, &servaddr.sin_addr) != 1) { fprintf(stderr, "ERROR: invalid IP address '%s'\n", server_ip); close(sockfd); fclose(fin); return -1; } char buf[BUF_SIZE]; // Читаем файл блоками и каждый блок отправляем одной UDP‑датаграммой. for (;;) { size_t n = fread(buf, 1, sizeof(buf), fin); if (n > 0) { ssize_t sent = sendto(sockfd, buf, n, 0, (struct sockaddr *) &servaddr, sizeof(servaddr)); if (sent < 0 || (size_t) sent != n) { perror("sendto"); close(sockfd); fclose(fin); return -1; } } // Если прочитали меньше, чем размер буфера — это EOF или ошибка. if (n < sizeof(buf)) { if (ferror(fin)) { perror("fread"); close(sockfd); fclose(fin); return -1; } break; // EOF. } } if (fclose(fin) == EOF) { perror("fclose(input_file)"); } // Отправляем серверу маркер конца передачи. ssize_t sent = sendto(sockfd, END_MARKER, strlen(END_MARKER), 0, (struct sockaddr *) &servaddr, sizeof(servaddr)); if (sent < 0 || (size_t) sent != strlen(END_MARKER)) { perror("sendto(END_MARKER)"); close(sockfd); return -1; } printf("File '%s' sent to %s:%d, END marker transmitted.\n", input_path, server_ip, port); close(sockfd); return 0; }