Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have a client server communication, I wrote the following server to handle the incoming message, but If the message is bigger than the buffer than it will be lost. How can I receive the whole packages in case if the messages are bigger than the buffer size? Is there any possibility, or I have to force the client(send a message at the begging with the maximum buffer size) to send a message within the buffer size?

msg ='' 
while( True ):                 
     msg += server.recv( 20480 )                                    
     aSplit = msg.partition( "</packet>" ) 
     #We received the full message
     while( aSplit[ 1 ] == "</packet>" ):                           
          messagehandler(  aSplit[ 0 ] + "</packet>" )                        
          msg = aSplit[ 2 ]
          aSplit = msg.partition( "</packet>" )
share|improve this question

1 Answer

up vote 3 down vote accepted

When dealing with any kind of packetised message format, you only really have two choices:

  1. Make sure your buffer is big enough to deal with the whole message.
  2. Write your code so that it can parse partial messages.

When I say "buffer", though, I don't mean the parameter for recv() - you can make that as small as you like, and just go around your while loop multiple times until you have a whole message.

So, to take the buffering approach you could do something like this:

msg = ''
while True:
    msg += server.recv(8192)
    while True:
        aSplit = msg.partition("</packet>")
        if not aSplit[1]:
            break
        messagehandler(aSplit[0] + "</packet>")
        msg = aSplit[2]

This works because if </packet> isn't found then partition() still returns a 3-tuple where the first item is the entire string and the other two are empty. So, all the while that partition() returns a non-empty string for the separator then a packet has been found. As soon as that's empty, there's a partial packet in msg (or it's empty), so we go back to reading from the network until we get an entire packet again.

This does involve buffering up the whole message in the msg string, but that's fine unless you expect these messages to get very large (multiple megabytes) - this could happen if the messages include large files, for example. In this case you need to be more clever and do something like swap data out to disk or process the data as you receive it.

Let me know if I wasn't clear about any of that.

EDIT: I should add, it's generally a good idea to make sure the buffer (i.e. msg) doesn't get too large - if it does then you need to close the connection because something's gone wrong. This stops something feeding the application endless data until the memory runs out on the system, either accidentally or maliciously. Also, you need to be very sure that the string </packet> can't actually occur inside the message - that would split the message in half incorrectly.

share|improve this answer
When I'm sending 100kB message I'm still losing the end of the message – iUngi Jan 11 at 9:14
It sounds like you're exceeding the operating system's buffer to store the data. If you're using a TCP connection, for example, there's a limited amount of data you can send - this applies regardless of what your client is doing, it could be reading GB at a time and this would still happen. What you need to do on the sending end is pay attention to the return code from send() which will tell you how much data was sent. Your application must keep sending the rest in a loop until it's all sent. I suggest you read the Python sockets HOWTO. – Cartroo Jan 11 at 10:30
In particular, read the section Using a socket - I quote: Now we come to the major stumbling block of sockets - send and recv operate on the network buffers. They do not necessarily handle all the bytes you hand them (or expect from them), because their major focus is handling the network buffers. – Cartroo Jan 11 at 11:03

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.