通过socket实现文件上传和下载功能
1 背景说明
使用 Python 的 socket 模块可以实现简单的文件上传和下载功能,可支持文件、图片上传。
2 服务器端代码 (socket_fileupload_server.py)
服务器端负责接收客户端发送的文件并保存。
import socket
from datetime import datetime
def file_upload_server(host='127.0.0.1', port=12345, max_listen=5):
"""
定义一个文件上传服务器
:param host: IP地址,默认127.0.0.1
:param port: 端口,默认8080
:param max_listen: 最大监听数,默认5
:return: 无
"""
# 创建 socket 对象,采用IP4、字节流(tcp)进行通信
socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定地址和端口
socket_server.bind((host, port))
# 设置最大监听数
socket_server.listen(max_listen)
print(f'[{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}] 服务器启动,等待连接……')
# 接受客户端连接
client_socket, client_address = socket_server.accept()
print(f'[{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}] 连接来自:{client_address}')
# 接收文件名称
file_name = client_socket.recv(1024).decode('utf-8')
print(f'[{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}] 接收文件名称为:{file_name}')
# 接收文件数据
with open(file_name, 'wb') as f:
# 循环接收数据
while True:
# 获取数据,每次最大为1024B
data = client_socket.recv(1024)
# 如果接收数据为空,则跳出循环
if not data:
break
# 将接收的数据写入到文件
f.write(data)
print(f'[{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}] 文件 {file_name} 接收完成!')
# 关闭客户端连接
client_socket.close()
# 关闭服务器连接
socket_server.close()
print(f'[{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}] 服务器已关闭')
if __name__ == '__main__':
# 启动文件上传服务区器
file_upload_server()
3 客户端代码 (socket_fileupload_client.py)
客户端负责读取本地文件并将其发送到服务器。
import socket
from datetime import datetime
def file_upload_client(file_path, host='127.0.0.1', port=12345):
"""
定义一个文件上传客户端
:param file_path: 文件路径信息,格式为:d:/files/test.txt
:param host: IP地址,默认127.0.0.1
:param port: 端口,默认8080
:return:无
"""
# 创建 socket 对象,采用IP4、字节流(tcp)进行通信
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接服务器
client_socket.connect((host, port))
print(f'[{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}] 服务器连接成功!')
# 获取文件名,支持文件路径:d:/files/test.txt
file_name = file_path.split('/')[-1]
# 将文件名发送给服务器
client_socket.send(file_name.encode('utf-8'))
print(f'[{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}] 上传文件名为:{file_name}')
# 读取文件名
with open(file_path, 'rb') as f:
# 循环读取文件信息并发送
while True:
# 获取数据,每次最大为1024B
data = f.read(1024)
# 如果接收数据为空,则跳出循环
if not data:
break
# 将读取的数据发送给服务器
client_socket.send(data)
print(f'[{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}] 文件 {file_name} 发送完成!')
# 关闭连接
client_socket.close()
print(f'[{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}] 客户端已关闭')
if __name__ == '__main__':
# file_img_path = 'F:/Pictures/桌面.jpg'
# file_upload_client(file_img_path)
file_path = 'F:/Documents/测试文档.txt'
file_upload_client(file_path)