Skip to content

Instantly share code, notes, and snippets.

@alexandnpu
Created June 2, 2017 09:13
Show Gist options
  • Save alexandnpu/5bd3f2d84dc09466dffed7e47a6dd9b2 to your computer and use it in GitHub Desktop.
Save alexandnpu/5bd3f2d84dc09466dffed7e47a6dd9b2 to your computer and use it in GitHub Desktop.
During my work, i have to use a python client to talk to a protobuf server based on netty. I can not find some python helpers to parse the length prepender that netty adds to each protobuf message. So I wrote the following code.
# the following is talk to protobuf server based on netty 4.1.11.Final
ONE_BYTE_MASK = 0xffffffff << 7
TWO_BYTES_MASK = 0xffffffff << 14
THREE_BYTES_MASK = 0xffffffff << 21
FOUR_BYTES_MASK = 0xffffffff << 28
def how_many_bytes_this_length_take(package_len):
result = package_len & ONE_BYTE_MASK
if result == 0:
return 1
result = package_len & TWO_BYTES_MASK
if result == 0:
return 2
result = package_len & THREE_BYTES_MASK
if result == 0:
return 3
result = package_len & FOUR_BYTES_MASK
if result == 0:
return 4
return 5
def get_packet_len(sock):
one_byte = sock.recv(1)
one_byte_value, = unpack(">B", one_byte)
if one_byte_value >= 0:
return one_byte_value
result = one_byte_value & 127
one_byte = sock.recv(1)
one_byte_value, = unpack(">B", one_byte)
if one_byte_value >= 0:
one_byte_value = one_byte_value << 7
return result | one_byte_value
one_byte_value = (one_byte_value & 127) << 7
result = result | one_byte_value
one_byte = sock.recv(1)
one_byte_value, = unpack(">B", one_byte)
if one_byte_value >= 0:
one_byte_value = one_byte_value << 14
return result | one_byte_value
one_byte_value = (one_byte_value & 127) << 14
result = result | one_byte_value
one_byte = sock.recv(1)
one_byte_value, = unpack(">B", one_byte)
if one_byte_value >= 0:
one_byte_value = one_byte_value << 21
return result | one_byte_value
one_byte_value = (one_byte_value & 127) << 21
result = result | one_byte_value
one_byte = sock.recv(1)
one_byte_value, = unpack(">B", one_byte)
if one_byte_value < 0:
raise Exception("malformed package")
one_byte_value = (one_byte_value & 127) << 28
return result | one_byte_value
def generate_length_prepender(length):
num_of_bytes = how_many_bytes_this_length_take(length)
format_str = ">"
for i in range(num_of_bytes):
format_str += "B"
return pack(format_str, length)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment