[Tutor] Practicing with sockets

Danny Yoo dyoo at hashcollision.org
Fri Oct 31 19:38:45 CET 2014


On Fri Oct 31 2014 at 10:31:20 AM Bo Morris <crushed26 at gmail.com> wrote:

> Hello all, hope everyone is doing well.
>
> I have been practicing with sockets and I am trying to send a small png
> from the client to the server.
>


Hey Bo,

Very cool!  Socket programming is fun, because it lets your programs start
talking to other programs.  But it can get frustrating at times too, since
it's all about communication, and we know communcation can fail for so many
different reasons.  :P  We'll try to help where we can.

Just to make sure, you are probably following the Socket HOWTO:

    https://docs.python.org/2/howto/sockets.html

Reading code...


> import socket
>
> f = open('/Users/Bo/Desktop/logo_ONEConnxt.png', 'rb')
> strf = f.read()
> client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
> client_socket.connect(("ip.ip.ip.ip", 8999))
> client_socket.sendall(strf)
> f.close()
> exit()
>
>
This is problematic: the server code won't know up front how many bytes it
should expect to read from the socket.  That is, the code here is sending
"variable-length" message, and variable lengths are difficult to work with.

One common solution is to prefix the payload with a fixed-size byte
length.  That way, the server can read the fixed-size length first, and
then run a loop that reads the rest of the bytes.  This looks something
like:

    import struct
    # ...
    # Send the length...
    client_socket.send(struct.pack("!I", len(strf)))
    # followed by the content
    client_socket.sendall(strf)

Your client code will symmetrically read the first four bytes, use
struct.unpack() to find how how large the rest of the message is going to
be, and then do a loop until it reads the exact number of bytes.


Ok, I'm reading through the client code a bit more...

data = client_socket.recv(4029)
> f.write(data)
> client_socket.close()
>

You probably want to open the output file _after_ the socket has accepted.
Otherwise, it seems a bit premature to open that "f" file.  Also, don't
forget to close the "f" file once you've finished reading the bytes.  Also
note here that since recv() doesn't guarantee how many bytes you'll read at
a time, the byte-reading code needs to be in a loop.

Also, I strongly suggest that you place some logging messages in both your
client and server to trace where your programs are.  One distinguishing
feature of network programs is that they are typically long-running, and so
logs help to expose what the heck they're doing at a given time.

See:

    https://docs.python.org/2/howto/logging.html#logging-basic-tutorial
    https://docs.python.org/2/library/logging.html

As it stands, your server might not have ever accepted a message from your
client, and you'll still see an empty file, since the code is opening the
file for writing before listening for a request.  That's the other reason
why you want to move the file opening to _after_ the socket is accepted.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tutor/attachments/20141031/fa1e3031/attachment.html>


More information about the Tutor mailing list