使用asyncio
实现多客户端连接处理
- 代码框架:
import asyncio
async def handle_connection(reader, writer):
# 处理客户端连接
try:
while True:
# 异步读取客户端数据
data = await reader.read(1024)
if not data:
break
# 在这里进行异步I/O操作,比如读取文件
file_content = await asyncio.to_thread(read_file, 'example.txt')
# 处理数据
response = f"Server received: {data.decode()}, and file content: {file_content}"
# 异步写回数据给客户端
writer.write(response.encode())
await writer.drain()
finally:
writer.close()
async def read_file(file_path):
with open(file_path, 'r') as f:
return f.read()
async def main():
server = await asyncio.start_server(handle_connection, '127.0.0.1', 8888)
async with server:
await server.serve_forever()
if __name__ == "__main__":
asyncio.run(main())
- 关键步骤解释:
handle_connection
函数:这是处理每个客户端连接的异步函数。reader
和writer
分别用于从客户端读取数据和向客户端写入数据。使用await reader.read(1024)
异步读取客户端发送的数据。通过await asyncio.to_thread(read_file, 'example.txt')
调用read_file
函数,这里asyncio.to_thread
将阻塞的文件读取操作放在一个新线程中执行,实现异步I/O。最后,将处理结果异步写回客户端。
read_file
函数:负责读取文件内容。
main
函数:使用asyncio.start_server
启动服务器,绑定到127.0.0.1:8888
,并将handle_connection
函数作为处理每个连接的回调。async with server
和await server.serve_forever()
让服务器持续运行,等待客户端连接。
asyncio.run(main())
:在if __name__ == "__main__"
块中,使用asyncio.run
来运行主异步函数main
,启动整个服务器流程。
使用threading
模块实现多客户端连接处理
- 代码框架:
import socket
import threading
def handle_connection(client_socket):
try:
while True:
data = client_socket.recv(1024)
if not data:
break
file_content = read_file('example.txt')
response = f"Server received: {data.decode()}, and file content: {file_content}"
client_socket.send(response.encode())
finally:
client_socket.close()
def read_file(file_path):
with open(file_path, 'r') as f:
return f.read()
def main():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('127.0.0.1', 8888))
server_socket.listen(5)
while True:
client_socket, addr = server_socket.accept()
# 为每个客户端连接创建一个新线程
thread = threading.Thread(target=handle_connection, args=(client_socket,))
thread.start()
if __name__ == "__main__":
main()
- 关键步骤解释:
handle_connection
函数:处理单个客户端连接。通过client_socket.recv(1024)
接收客户端数据,调用read_file
函数读取文件内容,处理数据后通过client_socket.send
将结果发送回客户端。处理完后关闭客户端套接字。
read_file
函数:读取文件内容。
main
函数:创建一个TCP套接字,绑定到127.0.0.1:8888
并开始监听。在while True
循环中,每当有新客户端连接时,创建一个新的线程来处理该连接,将handle_connection
函数和客户端套接字作为参数传递给线程。每个线程独立处理客户端的请求,从而实现同时处理多个客户端连接。