import socket import sys import os import time def start_client(ip, port, path): if not os.path.exists(path): return client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) addr = (ip, port) (filename, filesize) = os.path.basename(path), os.path.getsize(path) try: print(f"\033[46m[客户端]\033[0m {ip}:{port},建立连接") while True: try: client_socket.sendto(b"SYN", addr) if client_socket.recv(1024) == b"SYN-ACK": break except socket.timeout: continue print(f"\033[46m[客户端]\033[0m 发送元数据:{filename}({filesize} 字节)") while True: try: client_socket.sendto(f"META|{filename}|{filesize}".encode(), addr) if client_socket.recv(1024) == b"META-ACK": break except socket.timeout: continue print("\033[46m[客户端]\033[0m 传输数据……") with open(path, 'rb') as f: while True: chunk = f.read(1400) if not chunk: break client_socket.sendto(chunk, addr) time.sleep(0.001) # 简单的流控制 print("\033[46m[客户端]\033[0m 释放连接") for _ in range(3): try: client_socket.sendto(b"FIN", addr) if client_socket.recv(1024) == b"FIN-ACK": break except socket.timeout: continue print("\033[46m[客户端]\033[0m 连接关闭") except KeyboardInterrupt: pass finally: client_socket.close() if __name__ == "__main__": if len(sys.argv) < 3: print("【用法】python3 file_sender.py :<端口> <文件路径>") sys.exit(1) try: (ip, port) = sys.argv[1].split(':') start_client(ip, int(port), sys.argv[2]) except ValueError: print("【错误】地址格式应为 IP:端口")