FAQ

On Fri, Sep 11, 2015 at 6:12 AM, James Harris wrote:
Thanks for your help, Chris. Using select() is a very good option. I tried
first without a timeout and even then this version of Windows does not
recognise Control-C until after the select() call returns (which needs
similar prompting as with the accept() call. However, select() with a
timeout allows the code to work both on Windows and Linux. Hooray!

For anyone else who is looking for this the earlier test code was changed to

port = 8880
import select
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setblocking(0)
s.bind(("", port))
s.listen(1)
while 1:
ready = select.select((s,), (), (), 0.5)
#print '(ready %s)' % repr(ready)
if (ready[0]):
try:
endpoint = s.accept()
except socket.error, details:
print 'Ignoring socket error:', repr(details)
continue
print '(endpoint %s)' % repr(endpoint)
if endpoint:
break

(Your indentation is looking like a single space, here. I would
suggest indenting a bit more, for readability; but it might just be an
artefact of posting.)


This is what I meant when I said you would be polling. Effectively,
you wake up your program every half-second, check if Ctrl-C has been
pressed, and if it hasn't, you go back to sleep again. This is pretty
inefficient.


Assuming you don't need stdin for any other purpose, one solution
would be to spin off a thread that simply watches for a keyboard
signal. I tested this on Windows 7 with 2.7.10 and 3.4.3, and it
appears to work:


import socket
import threading


# Python 2/3 compat
try: input = raw_input
except NameError: pass


PORT = 8880
mainsock = socket.socket()
mainsock.bind(("", PORT))
mainsock.listen(1)


def console():
     """Constantly read from stdin and discard"""
     try:
         while "moar console": input()
     except (KeyboardInterrupt, EOFError):
         socket.socket().connect(("127.0.0.1",PORT))


threading.Thread(target=console).start()


while "moar sockets":
     s = mainsock.accept()
     print("New connection: %r" % s)
     # Do whatever you want with the connection
     s.close()




As long as you have _some_ thread reading from the console, you can
get woken up by Ctrl-C. When that happens, it simply fires off a quick
socket connection to itself, thus waking up the main thread; and then
the main thread sees the KeyboardInterrupt. (I'm not sure why, but
instead of seeing KeyboardInterrupt in the console thread, I've been
seeing EOFError. Since I don't particularly care to explore the
problem, I just wrote the except clause to catch both.)


This eliminates the polling, but you have to sacrifice stdin to do it.
It may be worth bracketing all of that code with a platform check -
don't bother doing all this unless you're on Windows. Up to you.


Stupid Windows.


ChrisA

Search Discussions

Discussion Posts

Previous

Follow ups

Related Discussions

Discussion Navigation
viewthread | post
posts ‹ prev | 6 of 11 | next ›
Discussion Overview
grouppython-list @
categoriespython
postedSep 10, '15 at 6:24p
activeSep 11, '15 at 11:15p
posts11
users4
websitepython.org

People

Translate

site design / logo © 2017 Grokbase