"""
文件传输程序(带进度条版本)
功能说明:
服务端:接收文件
客户端:发送文件
使用方法:
1. 启动服务端(接收文件):
python file_transfer.py server [监听IP] [监听端口]
2. 发送文件到指定地址:
python file_transfer.py 文件路径 [服务器IP] [服务器端口]
示例:
# 监听所有接口的8888端口
python file_transfer.py server 0.0.0.0 8888
# 发送文件到指定服务器的8888端口
python file_transfer.py data.txt 192.168.1.100 8888
"""
import socket
import os
from tqdm import tqdm
import threading
import time
def run_server(host='127.0.0.1', port=12345):
"""
文件接收服务端
:param host: 监听地址
:param port: 监听端口
"""
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((host, port))
server_socket.listen(10)
print(f"[*] 监听 {host}:{port}")
try:
while True:
client_socket, addr = server_socket.accept()
print(f"[+] 连接来自 {addr}")
client_thread = threading.Thread(
target=handle_client,
args=(client_socket, addr)
)
client_thread.start()
except KeyboardInterrupt:
print("\n[!] 服务端关闭")
finally:
server_socket.close()
def handle_client(client_socket, addr):
"""处理单个客户端连接"""
try:
file_name = client_socket.recv(1024).decode('utf-8')
print(f"[*] 接收文件: {file_name}")
if os.path.exists(file_name):
client_socket.sendall(b'FileExists')
time.sleep(0.1)
print(f"[!] 文件 {file_name} 已存在,拒绝接收")
return
client_socket.send(b'FilenameReceived')
file_size = int(client_socket.recv(1024).decode('utf-8'))
client_socket.send(b'Filesize received')
progress = tqdm(total=file_size, unit='B', unit_scale=True, desc=f"接收 {file_name}")
with open(file_name, 'wb') as file:
received_size = 0
while received_size < file_size:
data = client_socket.recv(1024)
file.write(data)
received_size += len(data)
progress.update(len(data))
progress.close()
print(f"[√] 文件 {file_name} 接收完成")
except Exception as e:
print(f"[!] 客户端 {addr} 处理异常: {str(e)}")
finally:
client_socket.close()
def send_file(file_path, host='127.0.0.1', port=12345):
"""
发送文件到服务端
:param file_path: 要发送的文件路径
:param host: 服务端地址
:param port: 服务端端口
"""
if not os.path.exists(file_path):
print(f"[!] 文件 {file_path} 不存在")
return
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client_socket.connect((host, port))
print(f"[*] 已连接到 {host}:{port}")
file_name = os.path.basename(file_path)
print(f"[*] 准备发送文件: {file_name}")
client_socket.send(file_name.encode('utf-8'))
data = client_socket.recv(1024)
print(data)
file_size = os.path.getsize(file_path)
client_socket.send(str(file_size).encode('utf-8'))
client_socket.recv(1024)
progress = tqdm(total=file_size, unit='B', unit_scale=True, desc=f"发送 {file_name}")
with open(file_path, 'rb') as file:
while True:
data = file.read(1024)
if not data:
break
client_socket.send(data)
progress.update(len(data))
progress.close()
print(f"[√] 文件 {file_name} 发送完成")
except Exception as e:
print(f"[!] 错误发生: {str(e)}")
finally:
client_socket.close()
if __name__ == "__main__":
import sys
if len(sys.argv) > 1 and sys.argv[1] == 'server':
server_host = sys.argv[2] if len(sys.argv) > 2 else '127.0.0.1'
server_port = int(sys.argv[3]) if len(sys.argv) > 3 else 12345
run_server(server_host, server_port)
else:
if len(sys.argv) < 2:
print("使用方法:")
print(" 接收文件: python file_transfer.py server [IP] [端口]")
print(" 发送文件: python file_transfer.py 文件路径 [IP] [端口]")
sys.exit()
file_path = sys.argv[1]
send_host = sys.argv[2] if len(sys.argv) > 2 else '127.0.0.1'
send_port = int(sys.argv[3]) if len(sys.argv) > 3 else 12345
send_file(file_path, send_host, send_port)