我使用asyncio
在python3.5中编写tcp客户端
在阅读了关于高级流媒体API的How to detect write failure in asyncio?后,我尝试使用低级protocol
api实现。
class _ClientProtocol(asyncio.Protocol):
def connection_made(self, transport):
self.transport = transport
class Client:
def __init__(self, loop=None):
self.protocol = _ClientProtocol()
if loop is None:
loop = asyncio.get_event_loop()
self.loop = loop
loop.run_until_complete(self._connect())
async def _connect(self):
await self.loop.create_connection(
lambda: self.protocol,
'127.0.0.1',
8080,
)
# based on https://vorpus.org/blog/some-thoughts-on-asynchronous-api-design-in-a-post-asyncawait-world/#bug-3-closing-time
self.protocol.transport.set_write_buffer_limits(0)
def write(self, data):
self.protocol.transport.write(data)
def wait_all_data_have_been_written_or_throw():
pass
client = Client()
client.write(b"some bytes")
client.wait_all_data_have_been_written_or_throw()
根据python文档,我知道write
是非阻塞的,我希望wait_all_data_have_been_written_or_throw
告诉我所有数据是否已写入或中间是否发生了不良事件(如一个连接丢失了,但是我假设有更多的东西可以变坏,并且底层套接字已经返回异常了吗?)
标准库是否提供了这样做的方法?
答案 0 :(得分:1)
问题主要与TCP套接字功能有关,而不是asyncio实现本身。
让我们看一下以下代码:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.send(b'data')
成功send()
调用意味着数据已传输到套接字的内核空间缓冲区中,仅此而已。
数据不是通过有线发送的,不是由对等方接收的,显然不是由接收处理的。 实际发送由操作系统内核异步执行,用户代码无法控制它。
为什么wait_all_data_have_been_written_or_throw()
没有多大意义:没有错误写入并不假设通过对等方接收这些数据,但只是成功地从用户空间缓冲区移动到内核空间缓冲区。< / p>