views:

57

answers:

1

Hi,

I use asyncore to communicate with remote servers using "length:message"-type protocol. Can someone recommend me a way to read exact amount of bytes from socket? I was trying to use handle_read to fill internal buffer and call my function every time, checking for size of buffer, but it looked too ugly(Check if buffer is long enough to read length, check if buffer length is bigger than message length, read message, etc...). Is it possible to have something like "socket.read(bytes)" which would sleep until buffer is filled enough and return value?

+1  A: 

No. Sleeping would defeat the entire purpose of asynchronous IO.

However, this is remarkably simple to do with twisted.

from twisted.protocols import Int32StringReceiver

class YourProtocol(Int32StringReceiver):
    def connectionMade(self):
        self.sendString('This string will automatically have its length '
            'prepended before it\'s sent over the wire!')

    def receiveString(self, string):
        print ('Received %r, which came in with a prefixed length, but which '
            'has been stripped off for convenience.' % (string,))
Aaron Gallagher
I was hoping to avoid twisted, but this looks like a very nice solution. But, is there a way to deal with messages having slightly different format at the same time? Something like length:message:additional_data where additional data has fixed length but this length is not included in prefix length? for example "4:test:fixed_length_string", this happens only when special condition is met, but I need to access this additional_data too.
Riz
That makes it slightly more complicated, though not too terrible. Personally, I'd recommend using the `qbuf` third-party module to do this. I'll post an example of how to use it for this in a second.
Aaron Gallagher