082. 编写一个函数,实现简单的文件服务器功能
在 Python 中,可以使用 socket
模块来实现一个简单的文件服务器。这个服务器可以接收客户端的请求,发送文件内容给客户端,或者接收客户端上传的文件并保存到服务器上。
示例代码
以下代码实现了一个简单的文件服务器,支持文件上传和下载。
import socket
import threading
import os
def handle_client(client_socket, client_address, server_dir):
"""
处理客户端请求的函数
:param client_socket: 客户端套接字
:param client_address: 客户端地址
:param server_dir: 服务器文件目录
"""
print(f"连接来自 {client_address}")
try:
while True:
request = client_socket.recv(1024).decode('utf-8')
if not request:
break
command, *args = request.split()
if command == "UPLOAD":
file_name = args[0]
file_path = os.path.join(server_dir, file_name)
with open(file_path, 'wb') as file:
while True:
data = client_socket.recv(1024)
if data.endswith(b"<EOF>"):
file.write(data[:-5])
break
file.write(data)
print(f"文件 {file_name} 已上传")
elif command == "DOWNLOAD":
file_name = args[0]
file_path = os.path.join(server_dir, file_name)
if os.path.exists(file_path):
with open(file_path, 'rb') as file:
data = file.read()
client_socket.sendall(data + b"<EOF>")
else:
client_socket.sendall(b"File not found<EOF>")
elif command == "LIST":
files = os.listdir(server_dir)
file_list = "\n".join(files)
client_socket.sendall(file_list.encode('utf-8') + b"<EOF>")
else:
client_socket.sendall(b"Unknown command<EOF>")
finally:
client_socket.close()
print(f"连接 {client_address} 已关闭")
def start_file_server(host='127.0.0.1', port=65432, server_dir='server_files'):
"""
启动文件服务器
:param host: 服务器地址,默认为 localhost
:param port: 服务器端口,默认为 65432
:param server_dir: 服务器文件目录,默认为 'server_files'
"""
if not os.path.exists(server_dir):
os.makedirs(server_dir)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((host, port))
server_socket.listen()
print(f"文件服务器启动,监听地址 {host}:{port}")
try:
while True:
client_socket, client_address = server_socket.accept()
client_thread = threading.Thread(target=handle_client, args=(client_socket, client_address, server_dir))
client_thread.start()
except KeyboardInterrupt:
print("服务器关闭")
finally:
server_socket.close()
# 主函数
if __name__ == "__main__":
start_file_server()
代码说明
服务器初始化:
-
使用
socket.socket
创建一个 TCP 套接字。 -
使用
bind
方法绑定到指定的地址和端口。 -
使用
listen
方法开始监听连接请求。
处理客户端请求:
-
使用
accept
方法接受客户端的连接。 -
为每个客户端创建一个线程来处理请求。
支持以下命令:
-
UPLOAD <file_name>
:上传文件。 -
DOWNLOAD <file_name>
:下载文件。 -
LIST
:列出服务器上的文件。
文件上传:
-
接收文件内容并保存到指定目录。
-
使用
<EOF>
标记文件传输结束。
文件下载:
-
读取文件内容并发送给客户端。
-
使用
<EOF>
标记文件传输结束。
文件列表:列出服务器目录中的所有文件并发送给客户端。
异常处理:捕获异常并确保客户端连接在结束时正确关闭。
示例输出
假设运行上述代码,服务器将启动并监听指定的地址和端口。当客户端连接并发送请求时,服务器将处理请求并返回结果。
注意事项
安全性:
-
在实际应用中,需要对客户端的请求进行验证,避免路径遍历攻击。
-
可以添加身份验证机制,确保只有授权用户可以访问文件。
错误处理:在实际应用中,建议添加更详细的异常处理机制,以处理网络错误、文件读写错误等情况。
停止服务器:在实际应用中,可以设置一个条件变量或信号处理机制,以便在需要时停止服务器。
扩展功能
- 支持更多文件操作:添加文件删除、重命名等功能。
- 支持大文件传输:使用更高效的方式处理大文件传输,例如分块传输。
- 支持多用户:添加用户管理功能,支持多用户同时连接。
视频讲解
BiliBili: 视睿网络-哔哩哔哩视频 (bilibili.com)