An asyncio example
Ian Kelly
ian.g.kelly at gmail.com
Sat Jul 4 01:58:45 EDT 2015
On Fri, Jul 3, 2015 at 9:14 AM, Marko Rauhamaa <marko at pacujo.net> wrote:
>
>>> 1) is there a way to close just one direction of the connection?
>>
>> No. SOCK_STREAM sockets are always bidirectional.
>
> socket.shutdown(socket.SHUT_WR) does the trick.
>
> I think the asyncio.StreamWriter.write_eof() is the high-level
> equivalent.
I stand corrected. And you're also correct about write_eof: it causes
shutdown(SHUT_WR) to be called on the underlying socket once the
buffer has been written.
https://hg.python.org/cpython/file/34460219c0e0/Lib/asyncio/selector_events.py#l737
That said, just replacing the writer.close() with writer.write_eof()
in the OP's code doesn't seem to work; the server response comes back
empty.
This works:
>>> sock1, sock2 = socket.socketpair()
>>> sock1.send(b'REQUEST')
7
>>> sock1.shutdown(socket.SHUT_WR)
>>> sock2.recv(100)
b'REQUEST'
>>> sock2.send(b'RESPONSE')
8
>>> sock1.recv(100)
b'RESPONSE'
And this works:
import asyncio
import socket
def server(sock):
request = yield from asyncio.get_event_loop().sock_recv(sock, 100)
print("got request {!r}".format(request))
yield from asyncio.get_event_loop().sock_sendall(sock, b'RESPONSE')
def client(sock):
yield from asyncio.get_event_loop().sock_sendall(sock, b'REQUEST')
sock.shutdown(socket.SHUT_WR)
response = yield from asyncio.get_event_loop().sock_recv(sock, 100)
print("got response {!r}".format(response))
asyncio.get_event_loop().stop()
def connect():
clientsock, serversock = socket.socketpair()
clientsock.setblocking(False)
serversock.setblocking(False)
asyncio.async(client(clientsock))
asyncio.async(server(serversock))
connect()
asyncio.get_event_loop().run_forever()
I'm wondering whether there might be a bug in the higher-level
transport code that interferes with reading after calling write_eof.
More information about the Python-list
mailing list