Question

I am sending encrypted audio through the network in Python. This app works momentarily then breaks saying it must be a multiple of 16.

Not sure what I am doing wrong. Or where to look in the code to solve this.

I would appreciate any help you have to offer

EDIT * I believe I have it working now if anyone is interested in taking a look I made a google code project

http://code.google.com/p/mii-chat/

Was it helpful?

Solution

I did a quick scan of the code. All messages are sent after being encrypted, so the total data you send is a multiple of 16, plus 1 for the command. So far, so good.

On the decrypting side, you strip off the command, which leaves you with a message that is a multiple of 16 again. However, you are calling msg.strip() before you call decrypt_my_message. It is possible that the call to strip corrupts your encrypted data by removing bytes from the beginning or the end.

I will examine the code further, and edit this answer if I find anything else.


EDIT:

You are using space character for padding, and I suppose you meant to remove the padding using the strip call. You should change decrypt_my_message(msg.strip()) to decrypt_my_message(msg).strip().


You are using TCP to send the data, so your protocol is bound to give you headaches in the long term. I always send the length of the payload in my messages with this sort of custom protocol, so the receiving end can determine if it received the message block correctly. For example, you could use: CMD|LEN(2)|PAYLOAD(LEN) as your data frame. It means, one byte for command, two more bytes to tell the server how many bytes to expect, and LEN bytes of actual message. This way, your recv call can loop until it reads the correct amount. And more importantly, it will not attempt to read the next packet when/if they are sent back-to-back.

Alternatively, if your packets are small enough, you could go for UDP. It opens up another can of worms, but you know that the recv will only receive a single packet with UDP.

OTHER TIPS

msg = conn.recv(2024)
if msg:                
    cmd, msg = ord(msg[0]),msg[1:]
    if cmd == CMD_MSG:
        listb1.insert(END, decrypt_my_message(msg.strip()) + "\n")

The snippet above from your code reads 2024 bytes of data (which isn't a multiple of 16) and then (if the "if" statements are True) then calls decrypt_my_message with msg.strip() as the argument. Then decrypt_my_message complains that it was given a string whose length wasn't a multiple of 16. (I'm guessing that this is the problem. Have a look in the traceback to see if this is the line that causes the exception).

You need to call decrypt_my_message with a string of length n*16.

You might need to rethink your logic for reading the stream - or have something in the middle to buffer the calls to decrypt_my_message into chunks of n*16.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top