// client_tcp_pairs.c // TCP-клиент для лабораторной №8, вариант "во всех парах одинаковых символов // второй символ заменить на пробел". // Клиент читает входной файл и передаёт его содержимое серверу по TCP. #include // printf, fprintf, perror, FILE, fopen, fclose, fread #include // exit, EXIT_FAILURE, strtol #include // memset, strlen #include // errno #include // close, write #include // sockaddr_in, inet_pton, htons #include // socket, connect #include // типы сокетов #include // sockaddr_in #define BUF_SIZE 4096 int main(int argc, char *argv[]) { // Ожидаемые аргументы: // argv[1] - IP-адрес сервера (например, 127.0.0.1). // argv[2] - порт сервера. // argv[3] - путь к входному файлу. if (argc < 4) { fprintf(stderr, "Usage: %s \n", argv[0]); fprintf(stderr, "Example: %s 127.0.0.1 5000 input.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; } // Создаём TCP-сокет. int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("socket"); fclose(fin); return -1; } // Заполняем структуру адреса сервера. struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(port); // Переводим строковый IP в бинарную форму. 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; } // Устанавливаем TCP-соединение. if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { perror("connect"); close(sockfd); fclose(fin); return -1; } printf("Connected to %s:%d, sending file '%s'\n", server_ip, port, input_path); char buf[BUF_SIZE]; for (;;) { // Читаем блок из файла. size_t n = fread(buf, 1, sizeof(buf), fin); if (n > 0) { // Отправляем блок по TCP. size_t sent_total = 0; while (sent_total < n) { ssize_t sent = write(sockfd, buf + sent_total, n - sent_total); if (sent < 0) { perror("write"); close(sockfd); fclose(fin); return -1; } sent_total += (size_t)sent; } } // Если прочитали меньше, чем BUF_SIZE, либо 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)"); } // Корректно закрываем соединение, чтобы сервер получил EOF. if (shutdown(sockfd, SHUT_WR) < 0) { perror("shutdown"); } close(sockfd); printf("File '%s' sent to %s:%d, connection closed.\n", input_path, server_ip, port); return 0; }