I'm trying to develop a simple socket server that has a non-blocking accept (using settimeout) but I would like to be able to stop it using Ctrl-C (KeyboardInterrupt).
My code is this:
import socket
host = '127.0.0.1'
port = 5000
s = socket.socket()
s.settimeout(1)
s.bind((host, port))
s.listen(1)
print('Server started')
while True:
try:
conn, addr = s.accept()
except socket.timeout:
pass
except Exception as exc:
print(str(exc))
print('Server closing')
s.close()
break
except KeyboardInterrupt:
print('Server closing')
s.close()
break
else:
print('Connection from', addr)
But the KeyboardInterrupt is never caught because it happens inside the socket.timeout exception handler. This is the output when pressing Ctrl-C
c:\Users\JMatos\MEOCloud\Python>python file_server.py
Server started
Traceback (most recent call last):
File "file_server.py", line 40, in <module>
conn, addr = s.accept()
File "C:\Python35-32\lib\socket.py", line 195, in accept
fd, addr = self._accept()
socket.timeout: timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "file_server.py", line 40, in <module>
conn, addr = s.accept()
KeyboardInterrupt
Is there any way to catch the KeyboardInterrupt exception inside the socket.timeout exception handler?
My env is Windows 7P+SP1 x64, Python 3.5.2 32b.
Thanks in advance,
JM
The problem is not the socket timeout. The problem is where you're expecting the exception to be thrown. Change the code to:
try:
while True:
try:
conn, addr = s.accept()
except socket.timeout:
pass
except Exception as exc:
print(str(exc))
print('Server closing')
s.close()
break
else:
print('Connection from', addr)
except KeyboardInterrupt:
print('Server closing')
s.close()