Receive data from socket stream

s0suk3 at gmail.com s0suk3 at gmail.com
Mon Apr 28 10:26:13 EDT 2008


On Apr 28, 4:30 am, Nick Craig-Wood <n... at craig-wood.com> wrote:
> s0s... at gmail.com <s0s... at gmail.com> wrote:
> >  I wanted to ask for standard ways to receive data from a socket stream
> >  (with socket.socket.recv()). It's simple when you know the amount of
> >  data that you're going to receive, or when you'll receive data until
> >  the remote peer closes the connection. But I'm not sure which is the
> >  best way to receive a message with undetermined length from a stream
> >  in a connection that you expect to remain open. Until now, I've been
> >  doing this little trick:
>
> >  data = client.recv(256)
> >  new = data
> >  while len(new) == 256:
> >      new = client.recv(256)
> >      data += new
>
> >  That works well in most cases. But it's obviously error-prone. What if
> >  the client sent *exactly* two hundred and fifty six bytes? It would
> >  keep waiting for data inside the loop. Is there really a better and
> >  standard way, or is this as best as it gets?
>
> What you are missing is that if the recv ever returns no bytes at all
> then the other end has closed the connection.  So something like this
> is the correct thing to write :-
>
>   data = ""
>   while True:
>       new = client.recv(256)
>       if not new:
>           break
>       data += new
>
> From the man page for recv
>
>   RETURN VALUE
>
>        These calls return the number of bytes received, or -1 if an
>        error occurred.  The return value will be 0 when the peer has
>        performed an orderly shutdown.
>
> In the -1 case python will raise a socket.error.
>
> --
> Nick Craig-Wood <n... at craig-wood.com> --http://www.craig-wood.com/nick

But as I said in my first post, it's simple when you know the amount
of data that you're going to receive, or when you'll receive data
until the remote peer closes the connection. But what about receiving
a message with undetermined length in a connection that you don't want
to close? I already figured it out: in the case of an HTTP server/
client (which is what I'm doing), you have to look for an empty line
in the message, which signals the end of the message headers. As for
the body, you have to look at the Content-Length header, or, if the
message body contains the "chunked" transfer-coding, you have to
dynamically decode the encoding. There are other cases but those are
the most influent.

BTW, has anybody used sockets as file-like objects
(client.makefile())? Is it more secure? More efficient?

Sebastian



More information about the Python-list mailing list