11# -*- coding: utf-8; -*-
22"""A simplistic message protocol.
33
4- This can be used over a TCP socket, to provide rudimentary message framing and
5- stream re-synchronization.
4+ This adds rudimentary message framing and stream re-synchronization on top of a
5+ stream-based transport layer such as TCP.
6+
7+ **Technical details**
68
79A message consists of a header and a body, where:
810
1517 These don't need to be number characters, any Unicode codepoints below 127 will do.
1618 It's unlikely more than (127 - 32)**2 = 95**2 = 9025 backwards incompatible versions
1719 of this protocol will be ever needed, even in the extremely unlikely case this code
18- ends up powering someone's starship in the 31st century.
20+ ends up powering someone's 31st century starship .
1921 literal "l": start of message length field
2022 utf-8 string, containing the number of bytes in the message body
2123 In other words, `str(len(body)).encode("utf-8")`.
22- literal ";": end of message length field (in v1 , also the end of the header)
24+ literal ";": end of message length field (in v01 , also the end of the header)
2325 body:
2426 arbitrary payload, exactly as many bytes as the header said.
2527"""
@@ -43,7 +45,7 @@ def sendmsg(body, sock):
4345 """
4446 buf = BytesIO ()
4547 buf .write (b"\xff " ) # sync byte
46- buf .write (b"v1 " ) # message protocol version
48+ buf .write (b"v01 " ) # message protocol version
4749 # message body length
4850 buf .write (b"l" )
4951 buf .write (str (len (body )).encode ("utf-8" ))
@@ -138,19 +140,19 @@ def read_header():
138140 If successful, drop the header from the receive buffer.
139141 """
140142 val = unbox (buf ).getvalue ()
141- while len (val ) < 4 :
143+ while len (val ) < 5 :
142144 val = lowlevel_read ()
143145 # BEWARE: val[0] == 255, but val[0:1] == b"\xff".
144146 if val [0 :1 ] != b"\xff " : # sync byte
145147 raise MessageParseError
146- if val [1 :3 ] != b"v1 " : # protocol version 1
148+ if val [1 :4 ] != b"v01 " : # protocol version 01
147149 raise MessageParseError
148- if val [3 : 4 ] != b"l" : # length of body field
150+ if val [4 : 5 ] != b"l" : # length of body field
149151 raise MessageParseError
150152 while b";" not in val : # end of length of body field
151153 val = lowlevel_read ()
152154 j = val .find (b";" )
153- body_len = int (val [4 :j ].decode ("utf-8" ))
155+ body_len = int (val [5 :j ].decode ("utf-8" ))
154156 buf << BytesIO (val [(j + 1 ):])
155157 return body_len
156158
0 commit comments