I'm trying to write a server in Python to communicate with a pre-existing client whose message packets are ASCII strings, but prepended by four-byte unsigned integer values representative of the length of the remaining string.
I've done a receiver, but I'm sure there's a a more pythonic way. Until I find it, I haven't done the sender. I can easily calculate the message length, convert it to bytes and transmit the message.The bit I'm struggling with is creating an integer which is an array of four bytes.
Let me clarify: If my string is 260 characters in length, I wish to prepend a big-endian four byte integer representation of 260. So, I don't want the ASCII string "0260" in front of the string, rather, I want four (non-ASCII) bytes representative of 0x00000104.
My code to receive the length prepended string from the client looks like this:
sizeBytes = 4 # size of the integer representing the string length # receive big-endian 4 byte integer from client data = conn.recv(sizeBytes) if not data: break dLen = 0 for i in range(sizeBytes): dLen = dLen + pow(2,i) * data[sizeBytes-i-1] data = str(conn.recv(dLen),'UTF-8')
I could simply do the reverse. I'm new to Python and feel that what I've done is probably longhand!!
1) Is there a better way of receiving and decoding the length?
2) What's the "sister" method to encode the length for transmission?
The struct module is helpful here
import struct msg = 'some message containing 260 ascii characters' length = len(msg) encoded_length = struct.pack('>I', length)
encoded_length will be a string of 4 bytes with value '\x00\x00\x01\x04'
length = struct.unpack('>I', received_msg[:4])
An example using
import asyncio import struct def send_message(writer, message): data = message.encode() size = struct.pack('>L', len(data)) writer.write(size + data) async def receive_message(reader): data = await reader.readexactly(4) size = struct.unpack('>L', data) data = await reader.readexactly(size) return data.decode()
The complete code is here
User contributions licensed under CC BY-SA 3.0