今天我们来聊聊 Python Socket编程的高级用法。在实际应用中,我们经常需要处理大量的并发连接,这时候就需要用到一些高级的技巧,比如多线程、异步IO等。话不多说,开始吧。
一、多线程
- 创建一个服务器,同时处理多个客户端请求。
import socket import threading # 定义一个处理客户端请求的函数 def handle_client(client_socket): request = client_socket.recv(1024) print(f"Received: {request}") client_socket.send(b"ACK!") client_socket.close() # 定义主函数 def main(): server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(("0.0.0.0", 9999)) server.listen(5) print("Listening on port 9999...") while True: # 当有客户端连接时,创建一个新的线程来处理该客户端的请求 client, addr = server.accept() print(f"Accepted connection from: {addr[0]}:{addr[1]}") client_handler = threading.Thread(target=handle_client, args=(client,)) client_handler.start() if __name__ == "__main__": main()
我们创建了一个简单的服务器,监听端口9999。当有客户端连接时,我们使用多线程的方式处理每个客户端的请求。这样可以大大提高服务器的并发处理能力。
二、异步IO
1.使用asyncio库实现异步IO。
import asyncio
import socket
# 定义一个处理客户端请求的异步函数
async def handle_client(reader, writer):
addr = writer.get_extra_info('peername')
print(f"Connection from: {addr}")
while True:
data = await reader.read(100)
if not data:
break
print(f"Received: {data}")
writer.write(data)
await writer.drain()
# 定义主函数
async def main():
server = await asyncio.start_server(handle_client, '127.0.0.1', 8888)
addr = server.sockets[0].getsockname()
print(f"Serving on: {addr}")
async with server:
await server.serve_forever()
if __name__ == "__main__":
asyncio.run(main())
当有客户端连接时,我们使用异步的方式读取客户端发送的数据,并将数据原样返回给客户端。这样可以避免因为阻塞导致的性能问题。需要注意的是,由于异步IO是基于事件循环的,所以在使用时需要遵循一定的规则,比如不能在异步函数中直接调用阻塞式的API。
当然,除了多线程和异步IO,Python Socket编程还有很多高级用法:
三、非阻塞IO
- 使用select模块实现非阻塞IO。
import socket
import select
server = socket.socket(socket.AF_INET, socke