socket.unbind or socket.unlisten? - socket.error: (48, 'Addressalready in use')

Discussion in 'Python' started by Laszlo Nagy, Jan 27, 2009.

  1. Laszlo Nagy

    Laszlo Nagy Guest

    I have a program that uses socket.bind() and socket.listen() frequently.
    After that program stops, it is not able to bind() again for a while:

    File "/home/gandalf/Python/Lib/orb/accesspoints/srvtcp.py", line 27, in
    __init__
    self.serversocket.bind((self.listen_address,self.port))
    File "<string>", line 1, in bind
    socket.error: (48, 'Address already in use')


    The problem with this, is that this server program SOMETIMES need to be
    restarted very quickly. I tried to find the solution in the socket
    module. But there is no "socket.unbind" or "socket.unlisten". How can I
    tell the OS that I do not want to listen on that address anymore, so
    other programs can bind on it immediatelly?

    (Yes I know that I can use setsockopt to allow listening multiple
    sockets on the same address, but this is NOT what I need...)

    Thanks,

    Laszlo
    Laszlo Nagy, Jan 27, 2009
    #1
    1. Advertising

  2. Laszlo Nagy

    Mark Wooding Guest

    Re: socket.unbind or socket.unlisten? - socket.error: (48, 'Address already in use')

    Laszlo Nagy <> writes:

    > I have a program that uses socket.bind() and socket.listen()
    > frequently. After that program stops, it is not able to bind() again for a
    > while:


    This is the usual TIME-WAIT problem. The TCP protocol requires one end
    of the connection (whichever actually started the close) to keep a
    record of it for a while after it closes, in order to avoid confusion
    caused by old packets.

    > The problem with this, is that this server program SOMETIMES need to be
    > restarted very quickly.


    The usual solution is to set the SO_REUSEADDR socket option before
    binding. This is safe for listening sockets.

    Here's an interactive session.

    In [1]: import socket as S

    In [2]: def make_server_socket():
    ...: sk = S.socket(S.AF_INET, S.SOCK_STREAM)
    ...: sk.bind(('', 12345))
    ...: sk.listen(5)
    ...: return sk
    ...:

    In [3]: def serve_client(sk):
    ...: (nsk, addr) = sk.accept()
    ...: nsk.send('Hello.\n')
    ...: nsk.close()
    ...:

    In [4]: sk = make_server_socket()

    In [5]: serve_client(sk)

    (At this point, I connect to the server in another terminal.)

    In [6]: sk.close()

    In [7]: sk = make_server_socket()
    [...]
    error: (98, 'Address already in use')

    And to confirm that it's TIME-WAIT that's stopping us:

    [ponder ~]netstat -n | grep 12345
    tcp 0 0 127.0.0.1:12345 127.0.0.1:49988 TIME_WAIT

    If I change make_server_socket, then everything works fine.

    In [8]: def make_server_socket():
    ...: sk = S.socket(S.AF_INET, S.SOCK_STREAM)
    ...: sk.setsockopt(S.SOL_SOCKET, S.SO_REUSEADDR, 1)
    ...: sk.bind(('', 12345))
    ...: sk.listen(5)
    ...: return sk
    ...:

    In [10]: sk = make_server_socket()

    In [11]: serve_client(sk)

    In [13]: sk.close()

    In [14]: sk = make_server_socket()

    Done.

    If you try this, note that both the old, closed socket /and/ the new one
    must have SO_REUSEADDR set on them. If you try this interactively,
    you'll have to wait for the non-SO_REUSEADDR socket to leave TIME-WAIT
    before you can bind. But once you've done that, it'll work fine from
    then on.

    -- [mdw]
    Mark Wooding, Jan 27, 2009
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jean-Paul Calderone
    Replies:
    0
    Views:
    952
    Jean-Paul Calderone
    Jan 27, 2009
  2. Laszlo Nagy
    Replies:
    0
    Views:
    532
    Laszlo Nagy
    Feb 1, 2009
  3. Steve Holden
    Replies:
    0
    Views:
    650
    Steve Holden
    Feb 1, 2009
  4. Steve Holden
    Replies:
    1
    Views:
    705
  5. Hendrik van Rooyen
    Replies:
    0
    Views:
    562
    Hendrik van Rooyen
    Feb 2, 2009
Loading...

Share This Page