| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 |
- 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 <IP>:<端口> <文件路径>")
- sys.exit(1)
- try:
- (ip, port) = sys.argv[1].split(':')
- start_client(ip, int(port), sys.argv[2])
- except ValueError:
- print("【错误】地址格式应为 IP:端口")
|