在 Linux 和 Windows 之间可以用python程序实现双向文件传输,通过创建一个简单的文件传输程序来实现。该程序将使用套接字socket通信,允许任意一端发送或接收文件。这是在我的那篇实现python两个进程之间相互通信的基础上拓展的(不过只看这一篇文章也行),那篇文章传输的数据是字符串类型,今天我来实现文件的传输。
服务器端代码 (Linux 和 Windows 通用)
服务器端代码将在任何操作系统上运行(不过要确保服务器端有静态IP,一般Windows下的IP都是动态分配的),它将监听连接并处理发送或接收文件的请求。
import socket
import os
def send_file(conn, file_path):
if not os.path.exists(file_path):
conn.sendall(b'FILE_NOT_FOUND')
return
file_extension = os.path.splitext(file_path)[1]
conn.sendall(file_extension.encode())
with open(file_path, 'rb') as file:
file_data = file.read()
conn.sendall(file_data)
print(f"文件 {file_path} 发送完成")
def receive_file(conn, save_path):
file_extension = conn.recv(1024).decode()
with open(save_path + file_extension, 'wb') as file:
while True:
file_data = conn.recv(1024)
if not file_data:
break
file.write(file_data)
print(f"文件接收完成,保存为 {save_path + file_extension}")
def start_server(host='0.0.0.0', port=12345):
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((host, port))
server_socket.listen(1)
print(f"服务器已启动,监听 {host}:{port}...")
while True:
conn, addr = server_socket.accept()
print(f"已连接到客户端: {addr}")
action = conn.recv(1024).decode()
if action == 'send':
receive_file(conn, 'received_file')
elif action == 'receive':
send_file(conn, 'server_file.txt') # 服务器端默认发送 server_file.txt
else:
print("未知操作")
conn.close()
if __name__ == '__main__':
start_server()
客户端代码 (Linux 和 Windows 通用)
客户端代码可以在任何操作系统上运行,它将连接到服务器并发送或请求接收文件。send_file()函数和receive_file()函数在服务端和客户端是一样的。服务端与客户端的区别在于客户端可以主动选择请求接收文件,而服务端只能够被动响应客户端的请求来发送文件。(当然,也可以不响应客户端的请求)
import socket
import os
def send_file(client_socket, file_path):
if not os.path.exists(file_path):
print("文件未找到")
return
file_extension = os.path.splitext(file_path)[1]
client_socket.sendall(file_extension.encode())
with open(file_path, 'rb') as file:
file_data = file.read()
client_socket.sendall(file_data)
print(f"文件 {file_path} 发送完成")
def receive_file(client_socket, save_path):
file_extension = client_socket.recv(1024).decode()
with open(save_path + file_extension, 'wb') as file:
while True:
file_data = client_socket.recv(1024)
if not file_data:
break
file.write(file_data)
print(f"文件接收完成,保存为 {save_path + file_extension}")
def start_client(host='<服务器IP地址>', port=12345, action='send', file_path='client_file.txt'):
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((host, port))
print("已连接到服务器")
client_socket.sendall(action.encode())
if action == 'send':
send_file(client_socket, file_path)
elif action == 'receive':
receive_file(client_socket, 'received_file')
else:
print("未知操作")
client_socket.close()
if __name__ == '__main__':
start_client()
关键步骤
-
准备文件:
- 在服务器端和客户端的目录中,确保有要发送的文件(例如
server_file.txt
和client_file.txt
)。
- 在服务器端和客户端的目录中,确保有要发送的文件(例如
-
启动服务器:
- 在任意一端(Linux 或 Windows)启动服务器端代码。
-
启动客户端:
- 在另一端(Linux 或 Windows)启动客户端代码。
实际运行
-
服务器端:
python3 server_script.py
请确保将
server_script.py
替换为实际服务器端脚本文件名(这是在终端使用的命令,确保python已经添加到环境变量中)。 -
客户端:
python3 client_script.py
将
<服务器IP地址>
替换为实际的服务器 IP 地址。action
参数可以是send
或receive
,file_path
是发送文件的路径。
示例场景
-
服务器发送文件:
- 在服务器端启动服务器。
- 在客户端启动客户端,指定
action='receive'
。
-
客户端发送文件:
- 在服务器端启动服务器。
- 在客户端启动客户端,指定
action='send'
和file_path='client_file.txt'
。
预期结果
- 无论哪端发送文件,另一端将接收并保存文件。
- 服务器端发送
server_file.txt
,客户端接收并保存为received_file.txt
。 - 客户端发送
client_file.txt
,服务器端接收并保存为received_file.txt
。
注意事项
- 文件路径: 确保在服务器端和客户端的目录中有要发送的文件。
- 网络配置: 确保服务器和客户端之间有网络连接,并且防火墙配置允许通过端口 12345 进行通信。
- 操作参数: 客户端代码中的
action
参数决定是发送文件还是接收文件。