heartbeats

Tom Anderson twic at urchin.earth.li
Fri Dec 9 18:48:55 CET 2005


On Fri, 9 Dec 2005, Sybren Stuvel wrote:

> Yves Glodt enlightened us with:
>
>> In detail I need a daemon on my central server which e.g. which in a 
>> loop pings (not really ping but you know what I mean) each 20 seconds 
>> one of the clients.

Do you mean pings one client every 20 sec, or each client every 20 sec?

> You probably mean "really a ping, just not an ICMP echo request".

What's a real ping, if not an ICMP echo request? That's pretty much the 
definitive packet for internetwork groping as far as i know. I think that 
the more generic sense of ping is a later meaning (BICouldVeryWellBW).

>> My central server, and this is important, should have a short timeout. 
>> If one client does not respond because it's offline, after max. 10 
>> seconds the central server should continue with the next client.
>
> I'd write a single function that pings a client and waits for a 
> response/timeout. It then should return True if the client is online, 
> and False if it is offline. You can then use a list of clients and the 
> filter() function, to retrieve a list of online clients.

That sounds like a good plan.

To do the timeouts, you want the settimeout method on socket:



import socket

def default_validate(sock):
 	return True

def ping(host, port, timeout=10.0, validate=default_validate):

 	"""Ping a specified host on the specified port. The timeout (in
 	seconds) and a validation function can be set; the validation
 	function should accept a freshly opened socket and return True if
 	it's okay, and False if not. This functions returns True if the
 	specified target can be connected to and yields a valid socket, and
 	False otherwise.

 	"""
 	sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 	sock.settimeout(timeout)
 	try:
 		sock.connect((host, port))
 	except socket.error:
 		return False
 	ok = validate(sock)
 	sock.close()
 	return ok



A potential problem with this is that in the worst case, you'll be 
spending a little over ten seconds on each socket; if you have a lot of 
sockets, that might mean you're not getting through them fast enough. 
There are two ways round this: handle several pings in parallel using 
threads, or use non-blocking sockets to handle several at once with a 
single thread.

tom

-- 
everything from live chats and the Web, to the COOLEST DISGUSTING
PORNOGRAPHY AND RADICAL MADNESS!!



More information about the Python-list mailing list