#!/usr/bin/env python3 import socket import struct import argparse import time import sys def recv_exact(sock, nbytes): chunks = [] got = 0 while got < nbytes: chunk = sock.recv(nbytes - got) if not chunk: raise ConnectionError("Соединение закрыто сервером") chunks.append(chunk) got += len(chunk) return b"".join(chunks) def recv_packet(sock): raw_len = recv_exact(sock, 4) (length,) = struct.unpack("!I", raw_len) if length > 16 * 1024 * 1024: raise ValueError(f"Слишком большой пакет: {length} байт") return recv_exact(sock, length) def send_packet(sock, data: bytes): sock.sendall(struct.pack("!I", len(data)) + data) def connect(host, port, timeout=10): return socket.create_connection((host, port), timeout=timeout) def main(): ap = argparse.ArgumentParser(description="TCP клиент (длина+данные) с периодической отправкой.") ap.add_argument("--host", default="127.0.0.1", help="Адрес сервера") ap.add_argument("--port", type=int, default=5000, help="Порт сервера") ap.add_argument("--message", default="Привет от клиента!", help="Сообщение (UTF-8)") ap.add_argument("--interval", type=float, default=5.0, help="Интервал отправки, сек (по умолчанию 5)") args = ap.parse_args() msg_bytes = args.message.encode("utf-8") sock = None try: while True: # Подключаемся, если не подключены if sock is None: try: sock = connect(args.host, args.port, timeout=10) sock.settimeout(15) # таймаут на операции, чтобы не зависать навсегда print(f"Подключено к {args.host}:{args.port}") except Exception as e: print(f"Не удалось подключиться: {e}. Повтор через {args.interval} сек.") time.sleep(args.interval) continue # Пытаемся отправить/получить try: send_packet(sock, msg_bytes) print(f"Отправлено серверу: {args.message!r}") resp = recv_packet(sock) try: print(f"Ответ сервера: {resp.decode('utf-8')!r}") except UnicodeDecodeError: print(f"Ответ сервера (bytes): {resp!r}") time.sleep(args.interval) except (ConnectionError, BrokenPipeError, TimeoutError, socket.timeout) as e: print(f"Потеряно соединение: {e}. Переподключение через {args.interval} сек.") try: sock.close() except Exception: pass sock = None time.sleep(args.interval) except KeyboardInterrupt: print("\nЗавершение по Ctrl+C.") finally: if sock: try: sock.close() except Exception: pass if __name__ == "__main__": main()