udpclient.py 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. import socket
  2. import sys
  3. import os
  4. import time
  5. def start_client(ip, port, path):
  6. if not os.path.exists(path): return
  7. client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  8. addr = (ip, port)
  9. (filename, filesize) = os.path.basename(path), os.path.getsize(path)
  10. try:
  11. print(f"\033[46m[客户端]\033[0m {ip}:{port},建立连接")
  12. while True:
  13. try:
  14. client_socket.sendto(b"SYN", addr)
  15. if client_socket.recv(1024) == b"SYN-ACK": break
  16. except socket.timeout: continue
  17. print(f"\033[46m[客户端]\033[0m 发送元数据:{filename}({filesize} 字节)")
  18. while True:
  19. try:
  20. client_socket.sendto(f"META|{filename}|{filesize}".encode(), addr)
  21. if client_socket.recv(1024) == b"META-ACK": break
  22. except socket.timeout: continue
  23. print("\033[46m[客户端]\033[0m 传输数据……")
  24. with open(path, 'rb') as f:
  25. while True:
  26. chunk = f.read(1400)
  27. if not chunk: break
  28. client_socket.sendto(chunk, addr)
  29. time.sleep(0.001) # 简单的流控制
  30. print("\033[46m[客户端]\033[0m 释放连接")
  31. for _ in range(3):
  32. try:
  33. client_socket.sendto(b"FIN", addr)
  34. if client_socket.recv(1024) == b"FIN-ACK": break
  35. except socket.timeout: continue
  36. print("\033[46m[客户端]\033[0m 连接关闭")
  37. except KeyboardInterrupt: pass
  38. finally: client_socket.close()
  39. if __name__ == "__main__":
  40. if len(sys.argv) < 3:
  41. print("【用法】python3 file_sender.py <IP>:<端口> <文件路径>")
  42. sys.exit(1)
  43. try:
  44. (ip, port) = sys.argv[1].split(':')
  45. start_client(ip, int(port), sys.argv[2])
  46. except ValueError:
  47. print("【错误】地址格式应为 IP:端口")