Python异步网络编程:原理、实践与优化策略
立即解锁
发布时间: 2025-09-01 02:03:08 阅读量: 5 订阅数: 28 AIGC 

### Python异步网络编程:原理、实践与优化策略
#### 1. 异步I/O基础与asyncio回调风格
在网络编程中,传统服务器一次只能处理一个客户端连接,其他客户端需等待当前连接关闭。为解决此问题,可采用异步编程风格,Python 3.4及更高版本的标准库中的`asyncio`框架是不错的选择。
下面是使用`asyncio`回调风格编写的服务器代码示例:
```python
import asyncio, zen_utils
address = zen_utils.parse_command_line('asyncio server using callbacks')
loop = asyncio.get_event_loop()
coro = loop.create_server(ZenServer, *address)
server = loop.run_until_complete(coro)
print('Listening at {}'.format(address))
try:
loop.run_forever()
finally:
server.close()
loop.close()
```
此代码中,`asyncio`框架将实际的套接字对象与协议代码隔离。框架负责处理远程地址查询,通过方法调用传递数据。在多数情况下,异步工作者会更复杂,如响应客户端需从文件系统读取文件或查询数据库时,客户端代码需在与文件系统、数据库及客户端的数据收发中依赖框架。此时,回调方法可能创建`futures`对象,在数据库或磁盘I/O完成后触发更多回调。
#### 2. 协程风格的asyncio
另一种为`asyncio`框架编写协议代码的方式是使用协程。协程是一种函数,在进行I/O操作时会暂停并将控制权返回给调用者。Python中实现协程最常见的方式是通过生成器,即包含一个或多个`yield`语句的函数。
以下是协程风格的`asyncio`服务器代码示例:
```python
#!/usr/bin/env python3
import asyncio, zen_utils
@asyncio.coroutine
def handle_conversation(reader, writer):
address = writer.get_extra_info('peername')
print('Accepted connection from {}'.format(address))
while True:
data = b''
while not data.endswith(b'?'):
more_data = yield from reader.read(4096)
if not more_data:
if data:
print('Client {} sent {!r} but then closed'.format(address, data))
else:
print('Client {} closed socket normally'.format(address))
return
data += more_data
answer = zen_utils.get_answer(data)
writer.write(answer)
if __name__ == '__main__':
address = zen_utils.parse_command_line('asyncio server using coroutine')
loop = asyncio.get_event_loop()
coro = asyncio.start_server(handle_conversation, *address)
server = loop.run_until_complete(coro)
print('Listening at {}'.format(address))
try:
loop.run_forever()
finally:
server.close()
loop.close()
```
与之前的服务器代码相比,此代码使用生成器,在之前代码进行阻塞操作等待操作系统响应的地方执行`yield`,从而避免阻塞`asyncio`子系统,允许多个工作者同时工作。PEP 380推荐这种协程方法,因为它能清晰显示生成器可能暂停的位置。不过,有些程序员不喜欢代码中有显式的`yield`语句,Python 2中的`gevent`和`eventlet`框架可将普通阻塞I/O请求的网络代码转换为异步I/O,但截至目前,这些框架尚未移植到Python 3。
#### 3. asyncore遗留模块
`asyncore`是Python标准库中的遗留模块,以下是使用`asyncore`框架编写服务器的代码示例:
```python
#!/usr/bin/env python3
import asyncore, asynchat, zen_utils
class ZenRequestHandler(asynchat.async_chat):
def __init__(self, sock):
asynchat.async_chat.__init__(self, sock)
self.set_terminator(b'?')
self.data = b''
def collect_incoming_data(self, more_data):
self.data += more_data
def found_terminator(self):
answer = zen_utils.get_answer(self.data + b'?')
self.push(answer)
self.initiate_send()
self.data = b''
class ZenServer(asyncore.dispatcher):
def handle_accept(self):
sock, address = self.accept()
ZenRequestHandler(sock)
if __name__ == '__main__':
address = zen_utils.parse_command_line('legacy “asyncore” server')
listener = zen_utils.create_srv_socket(address)
server = ZenServer(listener)
server.accepting = True
asyncore.loop()
```
此代码中,`ZenServer`对象未显式传递给`asyncore.loop()`方法或进行注册,但控制循环似乎知道服务可用,这表明该模块使用了模块
0
0
复制全文
相关推荐









