Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > How to receive a data file of unknown length using a python socket?

Reply
Thread Tools

How to receive a data file of unknown length using a python socket?

 
 
twgray
Guest
Posts: n/a
 
      07-18-2009
I am attempting to send a jpeg image file created on an embedded
device over a wifi socket to a Python client running on a Linux pc
(Ubuntu). All works well, except I don't know, on the pc client side,
what the file size is? The following is a snippet:

[code]
f = open("frame.jpg",mode = 'wb')
while True:
data = self.s.recv(MAXPACKETLEN)
if len(data) == 0:
break
recvd += len(data)
f.write(data)
f.close()
[end]

It appears to be locking up in 'data=self.s.recv(MAXPACKETLEN)' on
the final packet, which will always be less than MAXPACKETLEN.

I guess my question is, how do I detect end of data on the client side?
 
Reply With Quote
 
 
 
 
Irmen de Jong
Guest
Posts: n/a
 
      07-18-2009
twgray wrote:
> I am attempting to send a jpeg image file created on an embedded
> device over a wifi socket to a Python client running on a Linux pc
> (Ubuntu). All works well, except I don't know, on the pc client side,
> what the file size is?


You don't. Sockets are just endless streams of bytes. You will have to design some form
of 'wire protocol' that includes the length of the message that is to be read.
For instance a minimalistic protocol could be the following:
Send 4 bytes that contain the length (an int) then the data itself. The client reads 4
bytes, decodes it into the integer that tells it the length, and then reads the correct
amount of bytes from the socket.


--irmen
 
Reply With Quote
 
 
 
 
Tycho Andersen
Guest
Posts: n/a
 
      07-18-2009
On Sat, Jul 18, 2009 at 4:43 PM, Irmen de Jong<> wrote:
> twgray wrote:
>>
>> I am attempting to send a jpeg image file created on an embedded
>> device over a wifi socket to a Python client running on a Linux pc
>> (Ubuntu). *All works well, except I don't know, on the pc client side,
>> what the file size is?

>
> You don't. Sockets are just endless streams of bytes. You will have to
> design some form of 'wire protocol' that includes the length of the message
> that is to be read.
> For instance a minimalistic protocol could be the following:
> Send 4 bytes that contain the length (an int) then the data itself. The
> client reads 4 bytes, decodes it into the integer that tells it the length,
> and then reads the correct amount of bytes from the socket.


Exactly, sending the length first is the only way to know ahead of
time. Alternatively, if you know what the end of the data looks like,
you can look for that 'flag' as well, and stop trying to recv() after
that.

Some things that may be useful, though, are socket.settimeout() and
socket.setblocking(). More information is availible in the docs:
http://docs.python.org/library/socket.html.

You need to be careful with this, though, since network latency may
cause problems. Using these methods will keep your program from
sitting in recv() forever, though.

\t
--
http://tycho.ws
 
Reply With Quote
 
twgray
Guest
Posts: n/a
 
      07-18-2009
On Jul 18, 4:43*pm, Irmen de Jong <irmen.NOS...@xs4all.nl> wrote:
> twgray wrote:
> > I am attempting to send a jpeg image file created on an embedded
> > device over a wifi socket to a Python client running on a Linux pc
> > (Ubuntu). *All works well, except I don't know, on the pc client side,
> > what the file size is? *

>
> You don't. Sockets are just endless streams of bytes. You will have to design some form
> of 'wire protocol' that includes the length of the message that is to be read.
> For instance a minimalistic protocol could be the following:
> Send 4 bytes that contain the length (an int) then the data itself. The client reads 4
> bytes, decodes it into the integer that tells it the length, and then reads the correct
> amount of bytes from the socket.
>
> --irmen


Thanks for the reply. But, now I have a newbie Python question. If I
send a 4 byte address from the embedded device, how do I convert that,
in Python, to a 4 byte, or long, number?
 
Reply With Quote
 
MRAB
Guest
Posts: n/a
 
      07-18-2009
twgray wrote:
> On Jul 18, 4:43 pm, Irmen de Jong <irmen.NOS...@xs4all.nl> wrote:
>> twgray wrote:
>>> I am attempting to send a jpeg image file created on an embedded
>>> device over a wifi socket to a Python client running on a Linux pc
>>> (Ubuntu). All works well, except I don't know, on the pc client side,
>>> what the file size is?

>> You don't. Sockets are just endless streams of bytes. You will have to design some form
>> of 'wire protocol' that includes the length of the message that is to be read.
>> For instance a minimalistic protocol could be the following:
>> Send 4 bytes that contain the length (an int) then the data itself. The client reads 4
>> bytes, decodes it into the integer that tells it the length, and then reads the correct
>> amount of bytes from the socket.
>>

> Thanks for the reply. But, now I have a newbie Python question. If I
> send a 4 byte address from the embedded device, how do I convert that,
> in Python, to a 4 byte, or long, number?


If you send the length as 4 bytes then you'll have to decide whether
it's big-endian or little-endian. An alternative is to send the length
as characters, terminated by, say, '\n' or chr(0).
 
Reply With Quote
 
John Machin
Guest
Posts: n/a
 
      07-18-2009
On Jul 19, 8:04*am, twgray <twgray2...@gmail.com> wrote:

> send a 4 byte address from the embedded device, how do I convert that,
> in Python, to a 4 byte, or long, number?


struct.unpack() is your friend. Presuming the embedded device is
little-endian, you do:

the_int = struct.unpack('<I', four_bytes)[0]

See http://docs.python.org/library/struct.html
 
Reply With Quote
 
Nobody
Guest
Posts: n/a
 
      07-18-2009
On Sat, 18 Jul 2009 14:33:48 -0700, twgray wrote:

> It appears to be locking up in 'data=self.s.recv(MAXPACKETLEN)' on
> the final packet, which will always be less than MAXPACKETLEN.
>
> I guess my question is, how do I detect end of data on the client side?


recv() should return zero when the sender closes its end of the connection.

Is the sender actually closing its end? If you are unsure, use a packet
sniffer such as tcpdump to look for a packet with the FIN flag.

If you need to keep the connection open for further transfers, you need to
incorporate some mechanism for identifying the end of the data into the
protocol. As others have suggested, prefixing the data by its length is
one option. Another is to use an end-of-data marker, but then you need a
mechanism to "escape" the marker if it occurs in the data. A length prefix
is probably simpler to implement, but has the disadvantage that you can't
start sending the data until you know how long it is going to be.

 
Reply With Quote
 
John Machin
Guest
Posts: n/a
 
      07-19-2009
On Jul 19, 7:43*am, Irmen de Jong <irmen.NOS...@xs4all.nl> wrote:
> twgray wrote:
> > I am attempting to send a jpeg image file created on an embedded
> > device over a wifi socket to a Python client running on a Linux pc
> > (Ubuntu). *All works well, except I don't know, on the pc client side,
> > what the file size is? *

>
> You don't. Sockets are just endless streams of bytes. You will have to design some form
> of 'wire protocol' that includes the length of the message that is to be read.


Apologies in advance for my ignorance -- the last time I dipped my toe
in that kind of water, protocols like zmodem and Kermit were all the
rage -- but I would have thought there would have been an off-the-
shelf library for peer-to-peer file transfer over a socket
interface ... not so?
 
Reply With Quote
 
MRAB
Guest
Posts: n/a
 
      07-19-2009
Nobody wrote:
> On Sat, 18 Jul 2009 14:33:48 -0700, twgray wrote:
>
>> It appears to be locking up in 'data=self.s.recv(MAXPACKETLEN)' on
>> the final packet, which will always be less than MAXPACKETLEN.
>>
>> I guess my question is, how do I detect end of data on the client side?

>
> recv() should return zero when the sender closes its end of the connection.
>
> Is the sender actually closing its end? If you are unsure, use a packet
> sniffer such as tcpdump to look for a packet with the FIN flag.
>
> If you need to keep the connection open for further transfers, you need to
> incorporate some mechanism for identifying the end of the data into the
> protocol. As others have suggested, prefixing the data by its length is
> one option. Another is to use an end-of-data marker, but then you need a
> mechanism to "escape" the marker if it occurs in the data. A length prefix
> is probably simpler to implement, but has the disadvantage that you can't
> start sending the data until you know how long it is going to be.
>

You could send it in chunks, ending with a chunk length of zero.
 
Reply With Quote
 
twgray
Guest
Posts: n/a
 
      07-19-2009
On Jul 18, 7:33*pm, MRAB <pyt...@mrabarnett.plus.com> wrote:
> Nobody wrote:
> > On Sat, 18 Jul 2009 14:33:48 -0700, twgray wrote:

>
> >> It appears to be locking up in *'data=self.s.recv(MAXPACKETLEN)' on
> >> the final packet, which will always be less than MAXPACKETLEN.

>
> >> I guess my question is, how do I detect end of data on the client side?

>
> > recv() should return zero when the sender closes its end of the connection.

>
> > Is the sender actually closing its end? If you are unsure, use a packet
> > sniffer such as tcpdump to look for a packet with the FIN flag.

>
> > If you need to keep the connection open for further transfers, you need to
> > incorporate some mechanism for identifying the end of the data into the
> > protocol. As others have suggested, prefixing the data by its length is
> > one option. Another is to use an end-of-data marker, but then you need a
> > mechanism to "escape" the marker if it occurs in the data. A length prefix
> > is probably simpler to implement, but has the disadvantage that you can't
> > start sending the data until you know how long it is going to be.

>
> You could send it in chunks, ending with a chunk length of zero.


Thanks for the help!
 
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
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
Re: Can we send and receive data to and from Port Using Python ? Steve Holden Python 0 04-11-2008 12:52 PM
Assign an unknown value to an unknown variable Vincent Arnoux Ruby 1 08-11-2006 06:12 PM
using pthread to receive data on a socket and simultaneously play it using /dev/dsp kanchan C Programming 1 11-13-2004 10:33 PM
get last two in a length of unknown length? M. Clift Python 8 08-19-2004 06:26 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57