Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tornado socket.error on ARM

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

  • The port I'm attempting to listen on isn't otherwise in use
  • I don't specify an address, but it doesn't seem I need to since the Tornado "hello world" doesn't either (That demo app itself doesn't run either; it gives exactly the same error with a different line number)
  • The same app seemingly runs fine on x86 and x86_64 machines

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.

like image 243
Inaimathi Avatar asked Mar 25 '23 05:03

Inaimathi


1 Answers

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.

like image 62
Inaimathi Avatar answered Apr 06 '23 22:04

Inaimathi