I'm trying to run a small python webapp on a RasPi using the Tornado server, but whenever I try to start it, I get the error
Traceback (most recent call last):
File "main.py", line 78, in <module>
application.listen(8080)
File "/usr/local/lib/python2.7/dist-packages/tornado-3.0.1-py2.7.egg/tornado/web.py", line 1343, in listen
server.listen(port, address)
File "/usr/local/lib/python2.7/dist-packages/tornado-3.0.1-py2.7.egg/tornado/tcpserver.py", line 113, in listen
sockets = bind_sockets(port, address=address)
File "/usr/local/lib/python2.7/dist-packages/tornado-3.0.1-py2.7.egg/tornado/netutil.py", line 69, in bind_sockets
sock = socket.socket(af, socktype, proto)
File "/usr/lib/python2.7/socket.py", line 187, in __init__
_sock = _realsocket(family, type, proto)
socket.error: [Errno 97] Address family not supported by protocol
I'm reasonably sure I did everything properly
Is there a different call I need to make on ARM, or is this a bug somewhere in tornado/socket.py? Is there a workaround available?
Since it seems to be relevant, the Pi is running the latest Raspbian image from this page (downloaded from the second mirror a couple of days ago, so not the latest anymore). I'm currently trying out an older version, and will try out the latest if that doesn't work.
This turns out to have nothing to do with ARM. As per the answer artless noise
linked in one of his comments, it looks like Tornado gets confused if the system you start it up on supports IPv6, and this apparently includes the Raspberry Pi.
Starting the server up with
application.listen(8080, '0.0.0.0')
instead of just
application.listen(8080)
resolved the issue for me.
EDIT2: For cross-platform developers: the previous tactic I outlined actually doesn't work. Calling application.listen
binds the specified port even if the call errors (which seems like it might be a bug in Tornado). In other words, you need to determine what do before invoking listen
.
Since I run my app on GNU/Debian, the following worked well enough for me:
def listen(port):
(osName, machineName, osRelease, osVersion, machineType) = os.uname()
if re.search("arm", machineType):
logging.info("Running on ARM...")
application.listen(port, '0.0.0.0')
else:
logging.info("Running on x86...")
application.listen(port)
No idea how reliable this solution is under other OSes or architectures.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With