Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #93463 > unrolled thread
| Started by | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| First post | 2015-07-03 08:31 -0600 |
| Last post | 2015-07-03 23:58 -0600 |
| Articles | 3 — 2 participants |
Back to article view | Back to comp.lang.python
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: An asyncio example Ian Kelly <ian.g.kelly@gmail.com> - 2015-07-03 08:31 -0600
Re: An asyncio example Marko Rauhamaa <marko@pacujo.net> - 2015-07-03 18:14 +0300
Re: An asyncio example Ian Kelly <ian.g.kelly@gmail.com> - 2015-07-03 23:58 -0600
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2015-07-03 08:31 -0600 |
| Subject | Re: An asyncio example |
| Message-ID | <mailman.273.1435933923.3674.python-list@python.org> |
On Fri, Jul 3, 2015 at 4:28 AM, Adam Bartoš <drekin@gmail.com> wrote: > Hello, > > I'm experimenting with asyncio. I have composed the following code. There is > a server handler and a client handler. I didn't want to split the code into > two files so I just used a socketpair, inspired by example > https://docs.python.org/3/library/asyncio-stream.html#register-an-open-socket-to-wait-for-data-using-streams > . However, my code doesn't work – it blocks because both sides are trying to > read more data. But if I close the writer on one side (the commented line), > whole connection is closed. So > > 1) is there a way to close just one direction of the connection? No. SOCK_STREAM sockets are always bidirectional. > 2) In the blocked situaction even KeyboardInterrupt doesn't break the loop, > is that desired behavior? And why? I don't think so. When I tried this locally (using Python 3.4.0, so replacing "async def" with "def" and "await" with "yield from" and "loop.create_task" with "asyncio.async") pressing Ctrl-C did interrupt the loop. > 3) Are there some other issues with my code with respect to “best practices” > how to write a code like this? There are a couple of approaches you could take. Since your protocol is so far text-based, I would suggest adding '\n' to the ends of your messages and using reader.readline instead of reader.read. Alternatively, since the writer isn't planning to write anything further after its one message, just call writer.write_eof() (not writer.close) after the call to write.
[toc] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-07-03 18:14 +0300 |
| Message-ID | <87vbe1qnn6.fsf@elektro.pacujo.net> |
| In reply to | #93463 |
>> 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. Marko
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2015-07-03 23:58 -0600 |
| Message-ID | <mailman.286.1435989573.3674.python-list@python.org> |
| In reply to | #93465 |
On Fri, Jul 3, 2015 at 9:14 AM, Marko Rauhamaa <marko@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.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web