Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > need a thread to keep a socket connection alive?

Reply
Thread Tools

need a thread to keep a socket connection alive?

 
 
nephish@xit.net
Guest
Posts: n/a
 
      04-22-2006
hey there,

i have a script that waits for message packets from a data server over
a socket.
it goes a little like this:

while 1:
x+=1
databack = sockobj.recv(15
if databack:

print 'caught a message %s bytes ' % len(databack)
if len(databack) > 120:
message = databack[3:-3] #strip stx and enx
print '\n\n%s' % message
else:
break
print 'end data ack'


it works fine for a while, but the server requires that i send a
heartbeat ping every 600 seconds or it will terminate the connection.

so i also need something like
while 1:
sockobj.send(ping)
ping_acknowlage = sockobj.recv(4
time.sleep(550)



should i do this with threads? i dont want to interrupt the listening
cycle to send a ping.

appreciate any tips on how would be the best way to pull this off.

 
Reply With Quote
 
 
 
 
Rene Pijlman
Guest
Posts: n/a
 
      04-22-2006
http://www.velocityreviews.com/forums/(E-Mail Removed):
>i have a script that waits for message packets from a data server over
>a socket.


Using what network protocol?

>it works fine for a while, but the server requires that i send a
>heartbeat ping every 600 seconds or it will terminate the connection.

[...]
>should i do this with threads? i dont want to interrupt the listening
>cycle to send a ping.


If this is a TCP connection with a conversational protocol, you can't have
two threads reading bytes of the socket, without some sort of
coordination. When one thread parses the bytes it received, some bytes may
be part of the next message for the other thread.

You may be better off with asynchronous I/O and a state machine model.
http://squirl.nightmare.com/medusa/async_sockets.html
http://www.python.org/doc/lib/module-asyncore.html
http://twistedmatrix.com/projects/co...o/clients.html

--
René Pijlman
 
Reply With Quote
 
 
 
 
nephish@xit.net
Guest
Posts: n/a
 
      04-22-2006
thanks for the info, i will likely use the first link you posted with
the async module just to get it going, but i want to learn more about
twisted for later. there is even an O'Reilly book on it i see.
thanks for the tips,
sk

 
Reply With Quote
 
Ben Sizer
Guest
Posts: n/a
 
      04-24-2006
(E-Mail Removed) wrote:
> i have a script that waits for message packets from a data server over
> a socket.


If you're using TCP, bear in mind that you do not receive packets - you
receive a stream of data, which may usually come in the same quantities
as it was sent, but not always. If you don't take that into account,
you may end up missing a valid message because it arrived in several
parts.

> it works fine for a while, but the server requires that i send a
> heartbeat ping every 600 seconds or it will terminate the connection.


It is probably worth just reconnecting if necessary. After all, you
could be disconnected for other reasons too.

--
Ben Sizer

 
Reply With Quote
 
Roy Smith
Guest
Posts: n/a
 
      04-24-2006
(E-Mail Removed) wrote:

> hey there,
>
> i have a script that waits for message packets from a data server over
> a socket.
> it goes a little like this:
>
> while 1:
> x+=1
> databack = sockobj.recv(15
> if databack:
>
> print 'caught a message %s bytes ' % len(databack)
> if len(databack) > 120:
> message = databack[3:-3] #strip stx and enx
> print '\n\n%s' % message
> else:
> break
> print 'end data ack'


You need to go review how TCP works. All that it guarantees is that you
will receive bytes in the same order they were sent. It says nothing about
maintaining record boundaries. Just because you did a send(n) at one end,
it doesn't mean that you can expect to read n bytes in a single recv() call
at this end. Multiple send() calls could have their contents accumlated
into a single recv() call, or a single send() could get broken up into
several recv() calls.

If you want to read fixed-length messages (as you appear to be trying to do
with your recv(15), you need to build a buffering layer which reads from
the socket into a buffer and then doles out messages to a higher layer from
that buffer.

> it works fine for a while, but the server requires that i send a
> heartbeat ping every 600 seconds or it will terminate the connection.
>
> so i also need something like
> while 1:
> sockobj.send(ping)
> ping_acknowlage = sockobj.recv(4
> time.sleep(550)


This needs to be burried in a lower layer as well. You want to build some
kind of bufferedConnection class which hides all this gunk from your
application. You probably will want sendMessage() and recvMessage()
methods for your class. You probably want to have this class create a
thread to handle the low-level I/O asyncronously, and put the heatbeat
processing in there.

This is not a trivial problem. By the time you're done with it, you will
have learned a lot about how to communicate over a network.
 
Reply With Quote
 
Fredrik Lundh
Guest
Posts: n/a
 
      04-24-2006
Roy Smith wrote:

> If you want to read fixed-length messages (as you appear to be trying to do
> with your recv(15), you need to build a buffering layer which reads from
> the socket into a buffer and then doles out messages to a higher layer from
> that buffer.


> This is not a trivial problem. By the time you're done with it, you will
> have learned a lot about how to communicate over a network.


however, creating a buffered layer for reading is a trivial problem: just call
makefile on the socket object, and use the resulting object as a file handle:

>>> s = socket.socket()
>>> s.connect(("www.python.org", 80))
>>> s.send("GET / HTTP/1.0\n\n")

16
>>> f = s.makefile()
>>> f.readline()

'HTTP/1.1 200 OK\r\n'
>>> f.readline()

'Date: Mon, 24 Apr 2006 12:37:46 GMT\r\n'
>>> f.read(10)

'Server: Ap'
>>> f.read(10)

'ache/2.0.5'
>>> f.readline()

'4 (Debian GNU/Linux) DAV/2 SVN/1.1.4 mod_python/3.1.3 ...
>>> f.readline()

'Last-Modified: Mon, 24 Apr 2006 04:52:53 GMT\r\n'

etc.

</F>



 
Reply With Quote
 
Roy Smith
Guest
Posts: n/a
 
      04-24-2006
"Fredrik Lundh" <(E-Mail Removed)> wrote:
> however, creating a buffered layer for reading is a trivial problem: just call
> makefile on the socket object, and use the resulting object as a file handle:


The problem with that is that makefile() requires the socket to be in
blocking mode. If you're going to be implementing heartbeat, that's
probably not what you want.
 
Reply With Quote
 
Serge Orlov
Guest
Posts: n/a
 
      04-24-2006
(E-Mail Removed) wrote:
> hey there,
>
> i have a script that waits for message packets from a data server over
> a socket.
> it goes a little like this:
>
> while 1:
> x+=1
> databack = sockobj.recv(15
> if databack:
>
> print 'caught a message %s bytes ' % len(databack)
> if len(databack) > 120:
> message = databack[3:-3] #strip stx and enx
> print '\n\n%s' % message
> else:
> break
> print 'end data ack'
>
>
> it works fine for a while, but the server requires that i send a
> heartbeat ping every 600 seconds or it will terminate the connection.
>
> so i also need something like
> while 1:
> sockobj.send(ping)
> ping_acknowlage = sockobj.recv(4
> time.sleep(550)
>
>
>
> should i do this with threads? i dont want to interrupt the listening
> cycle to send a ping.
>
> appreciate any tips on how would be the best way to pull this off.


sockobj.settimeout(550)

before the loop and later in the loop:

try:
databack = sockobj.recv(15
except socket.timeout:
ping_server(sockobj)
continue

Also, as other people pointed out, you'd better make buffered socket
with .makefile() socket method.

 
Reply With Quote
 
Roy Smith
Guest
Posts: n/a
 
      04-24-2006
Serge Orlov <(E-Mail Removed)> wrote:
> sockobj.settimeout(550)
> [...]
> Also, as other people pointed out, you'd better make buffered socket
> with .makefile() socket method.


If I understand the docs for the socket module correctly, these two
suggestions are mutually incompatable.
 
Reply With Quote
 
Serge Orlov
Guest
Posts: n/a
 
      04-24-2006
Roy Smith wrote:
> Serge Orlov <(E-Mail Removed)> wrote:
> > sockobj.settimeout(550)
> > [...]
> > Also, as other people pointed out, you'd better make buffered socket
> > with .makefile() socket method.

>
> If I understand the docs for the socket module correctly, these two
> suggestions are mutually incompatable.


Perhaps this restriction was lifted?

>>> s = socket.socket()
>>> s.settimeout(15)
>>> s.connect(("www.python.org", 80))
>>> f = s.makefile()
>>> f.readline()


Traceback (most recent call last):
File "<pyshell#21>", line 1, in -toplevel-
f.readline()
File "C:\Python24\lib\socket.py", line 340, in readline
data = self._sock.recv(self._rbufsize)
timeout: timed out
>>>


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How keep python socket alive for ever by setting Keep alive flag. hisan Python 1 06-25-2012 05:30 PM
Re: socket.unbind or socket.unlisten? - socket.error: (48, 'Addressalready in use') Steve Holden Python 0 02-01-2009 12:45 PM
Re: socket.unbind or socket.unlisten? - socket.error: (48, 'Addressalready in use') Laszlo Nagy Python 0 02-01-2009 07:37 AM
socket.unbind or socket.unlisten? - socket.error: (48, 'Addressalready in use') Laszlo Nagy Python 1 01-27-2009 05:05 PM
Re: socket.unbind or socket.unlisten? - socket.error: (48,'Address already in use') Jean-Paul Calderone Python 0 01-27-2009 01:41 PM



Advertisments