Newbie question: how to keep a socket listening?

Discussion in 'Python' started by pwilkins, Jun 24, 2005.

  1. pwilkins

    pwilkins Guest

    First off I'm want to learn socket/network programming with python
    so a lot of what I ask is newbie related.

    I have written a test socket server that runs as a daemon.
    It listens on two sockets (say at ports 8000 and 9000) so that I can
    telnet over from another machine and get process info (ps type of info),
    one one port and control the server on the other port.

    What I want is to have the daemon run thread (A) which listens
    on port 8000, and then runs another thread (B) which listens 9000.

    Thread A monitors whether thread B is alive with a
    thread_B_.isSet() call.
    If thread B has terminated then thread A can exit when user tells
    it to, otherwise not.

    Thread B will terminate when user tells it to exit.

    I can start the daemon and connect to both ports just fine.
    If I leave the connections on using telnet for example, the connections
    keep working (stay alive). This part works.

    But I also want to be able to disconnect the telnet sessions,
    but leave the daemon server still listening on both ports so I can
    reconnect to both ports later.

    If I disconnect and try to reconnect within about 10secs it works fine.
    However if I stay disconnected from more than a minute then
    I cannot reconnect later. It seems as if the the server is not
    listening anymore....although the threads are still running
    i.e. the daemon is up.

    The message from telnet is:
    >>telnet: connect to address xxx.xxx.xxx.xxx: Connection refused


    Perhaps I do not understand the function of the following:
    socket.setdefaulttimeout(15)
    socket.settimeout(15.0)

    What is the difference between these??
    Yes I have read the python docs
    - setdefaulttimeout(timeout) Set the default timeout in floating
    seconds for new socket objects.
    whereas:
    - settimeout(value): Set a timeout on blocking socket operations.

    So what this means to me is that with setdefaulttimeout one can set
    a global timeout for new sockets, wheres with settimeout one can fine tune
    it after a socket has been created. This is probably all wrong.

    Any ideas as to what is causing the server to stop listening after I disconnect
    for a long period of time.

    Also does one have to do a socket.shutdown() before one does a socket.close??

    How should a server disconnect a client but keep listening for subsequent
    connections from other clients?

    I have included a summary of important code below.
    Let me know if should provide more or different info.

    Thanks a lot in advance.
    Pete

    -------------------------------------
    The program basically works as below:
    -------------------------------------
    (1) become a daemon

    (2) call server function which does the following (summarized):
    import socket
    ...

    HOST = ''

    socket.setdefaulttimeout(15)

    try:
    sa = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sa.bind((HOST, AdminPort))
    sa.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sa.settimeout(15.0)
    sa.listen(1)
    except:
    ## exit on failure

    ## run 2nd socket handler as thread
    # create an event to signal the completion of client handler thread
    client_handler_complete=threading.Event()
    client_handler_complete.clear()

    server_handler_thread = threading.Thread (None, ClientHandler, None, \
    (StateValues, client_handler_complete))
    try:
    server_handler_thread.start()
    except:
    ## exit on failure

    while 1: ## wait for a connection
    try:
    #...waiting for connection
    (client, address)=sa.accept()
    except sa.timeout:
    #...waiting for connection timeout
    continue
    except:
    continue ## for now ignore this!

    #...someone's connecting, so check if ipaddress is allowed
    remote = str(address[0])
    if Allowed_Hosts.has_key(remote):
    hostname = Allowed_Hosts[remote]
    Message = '%s connection accepted from: %s (%s:%s))' % \
    (FUNCNAME, hostname, address[0], address[1])
    log_message(StateValues, Message, 1)
    else:
    client.close()
    Message = '%s connection rejected from: %s' % (FUNCNAME, address)
    log_message(StateValues, Message, 1)
    continue

    socketfile = client.makefile()

    while 1: ## wait for user input
    data = ''
    data=read_data(socketfile)
    if not data or data == 'CR':
    continue
    else:
    Message = '%s input received: %s' % (FUNCNAME, data)
    log_debug_message(StateValues, Message)

    if data == 'q':
    ##disconnect client but keep waiting for connections
    ...
    client.close()

    elif data == 'x':
    ##disconnect client and shutdown server
    ...
    client.close()
    socketfile.close()
    sys.exit(0)
    ## wait for user input
    ## end wait for a connection

    (3) the thread which handles the second socket is coded like that above.
     
    pwilkins, Jun 24, 2005
    #1
    1. Advertising

  2. pwilkins

    ncf Guest

    I think your problem /may/ be in the following line of code:
    sa.listen(1)

    I believe what's happening is that the listen() creates a decremental
    counter of the number of connections to accept. Once it decrements to
    0, it won't accept any more connections. (I'm not at all sure, but that
    sounds like what it's doing.)

    One thing that I have noted is that once I am done with some internet
    program, the connection that program created is left in the waiting
    state. This might explain why, when you close your application and open
    it back up again a short amount of time later, the connection is
    refused.

    Another thought on this matter is that your end may be closing the
    connection, but the daemon end might not be closing the connection, so
    the listen counter may not increment back up to say "Hey, I'm available
    for another connection."

    Nevertheless, I'm also relatively new to Sockets, so my guess is
    probably just as good as your guess. :p (Hell, I couldn't get them
    fully right away, and read that it was easier to use
    asyncore.dispatcher for a daemon, so I'm using that!)

    If you find out the problem, please post it up here for all to learn
    from :)

    Oh, and just a suggestion, do something like a 'netstat -a -p --inet'
    on the daemon end. (Might not be the completely correct command =\)

    Hope that helps
    -Wes
     
    ncf, Jun 24, 2005
    #2
    1. Advertising

  3. On 2005-06-24, ncf <> wrote:

    > I think your problem /may/ be in the following line of code:
    > sa.listen(1)
    >
    > I believe what's happening is that the listen() creates a decremental
    > counter of the number of connections to accept. Once it decrements to
    > 0, it won't accept any more connections. (I'm not at all sure, but that
    > sounds like what it's doing.)


    The "1" tells the stack how many pending connections are allowed.

    --
    Grant Edwards grante Yow! I FORGOT to do the
    at DISHES!!
    visi.com
     
    Grant Edwards, Jun 24, 2005
    #3
  4. pwilkins

    pwilkins Guest

    On Fri, 24 Jun 2005 13:59:19 -0400, pwilkins wrote:

    > if data == 'q':
    > ##disconnect client but keep waiting for connections
    > ...
    > client.close()


    Sorry - made a mistake in my posting...
    the above should have been:

    if data == 'q':
    ##disconnect client but keep waiting for connections
    ...
    client.close()
    break # return to the wait for connections while loop

    Again thanks...
     
    pwilkins, Jun 24, 2005
    #4
  5. pwilkins

    pwilkins Guest

    On Fri, 24 Jun 2005 11:21:28 -0700, ncf wrote:

    > I think your problem /may/ be in the following line of code:
    > sa.listen(1)
    >
    > I believe what's happening is that the listen() creates a decremental
    > counter of the number of connections to accept. Once it decrements to
    > 0, it won't accept any more connections. (I'm not at all sure, but that
    > sounds like what it's doing.)

    Good point, will read up on socket.listen(x)

    > If you find out the problem, please post it up here for all to learn
    > from :)

    Will do that
    >
    > Oh, and just a suggestion, do something like a 'netstat -a -p --inet' on
    > the daemon end. (Might not be the completely correct command =\)


    I did that is how I know the ports are still begin held
    thx, pete
     
    pwilkins, Jun 24, 2005
    #5
  6. pwilkins

    ncf Guest

    Heh, like I said. I was not at all sure. :p

    Nevertheless, could this be the problem? =\
     
    ncf, Jun 25, 2005
    #6
  7. pwilkins

    Peter Hansen Guest

    ncf wrote:
    > Heh, like I said. I was not at all sure. :p
    >
    > Nevertheless, could this be the problem? =\


    You *may* correct, mainly because the OP's code doesn't appear to spawn
    off new threads to handle the client connections, which means he can
    handle only one connection at a time. Specifically, while he is talking
    to one client he is not also in an accept() call on the server socket,
    which means there will be (because of the listen(1) call) only a single
    pending connection allowed in the backlog.

    I haven't attempted a thorough analysis... just this much, trying to see
    whether it is obvious that the listen(1) is at fault -- and it's not
    obvious. I thought this response might clarify the meaning of listen(1)
    a little bit for some folks nevertheless.

    -Peter
     
    Peter Hansen, Jun 25, 2005
    #7
  8. On 2005-06-25, Peter Hansen <> wrote:

    > You *may* correct, mainly because the OP's code doesn't appear
    > to spawn off new threads to handle the client connections,
    > which means he can handle only one connection at a time.
    > Specifically, while he is talking to one client he is not also
    > in an accept() call on the server socket, which means there
    > will be (because of the listen(1) call) only a single pending
    > connection allowed in the backlog.


    But when he closes that connection, he calls accept again. And
    it's at that point where he tries to connect and can't. I
    think.

    Can the program be pared down to something smaller that
    demonstrates the problem?

    > I haven't attempted a thorough analysis... just this much,
    > trying to see whether it is obvious that the listen(1) is at
    > fault -- and it's not obvious. I thought this response might
    > clarify the meaning of listen(1) a little bit for some folks
    > nevertheless.


    He could change the 1 to a larger number and see if the
    behavior changes.

    --
    Grant Edwards grante Yow! I was giving HAIR
    at CUTS to th' SAUCER PEOPLE
    visi.com ... I'm CLEAN!!
     
    Grant Edwards, Jun 25, 2005
    #8
    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. Giovanni Tumiati
    Replies:
    2
    Views:
    348
    Grant Edwards
    Jun 25, 2005
  2. Jp Calderone
    Replies:
    1
    Views:
    356
    Grant Edwards
    Jun 25, 2005
  3. Jp Calderone
    Replies:
    2
    Views:
    404
    Grant Edwards
    Jun 25, 2005
  4. Spendius
    Replies:
    5
    Views:
    397
    Arne Vajhøj
    Oct 13, 2008
  5. hisan
    Replies:
    1
    Views:
    1,407
    Dan Stromberg
    Jun 25, 2012
Loading...

Share This Page