Newbie question: how to keep a socket listening?

P

pwilkins

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:
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.
 
N

ncf

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
 
G

Grant Edwards

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.
 
P

pwilkins

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...
 
P

pwilkins

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
 
P

Peter Hansen

ncf said:
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
 
G

Grant Edwards

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,955
Messages
2,570,117
Members
46,705
Latest member
v_darius

Latest Threads

Top