0
\$\begingroup\$

For my game I decided to not encrypt my packet's payload. Instead I'm just going to check everything on the server to make sure the packet is legitimate.

As I'm not doing any encryption, my packet's raw payload looks like this:

PacketID|Arg1|Arg2|Arg3[|Arg4...]

Now I want to encode those arguments, so if I have a | in for example a chat message, I can still handle my packet. How can I achieve this?

\$\endgroup\$
1
  • \$\begingroup\$ How do you print a % with printf()? Right, it's changed to %%. The other solution could be to define a data link escape (DLE) character like the `\`. \$\endgroup\$ – ott-- Jul 20 '13 at 16:42
2
\$\begingroup\$

There are any number of ways to do this. You could, for example, treat || as being a literal | and not your field separator. If your current process for decoding your packet involves first splitting it on single | tokens, you'll probably want to either

  • change the split so it uses a regular expression with a negative lookahead to avoid the || or
  • process the packet data linearly instead of pre-emptively splitting it.

That said, I would suggest instead that you don't transmit ASCII data as your packet payloads, but instead serialize them to an efficient binary representation (this is not the same as encrypting them). You'll have far fewer character-escape issues this way, because the structure of your chat packet (for example) will be something like four bytes to indicate a message length, followed by n bytes of character data that you know is the entire message.

(You can, of course, use the length-prefixing technique in an ASCII-format payload as well, as suggested by Byte56 in his answer.)

Alternatively, if you're going to use ASCII payload data for diagnostics and visibility, choose a format that is already known so you can leverage existing specifications for character escapes (or even better, existing 3rd party libraries). I really don't recommend ASCII transports for data that goes across the public internet, but if you are transmitting only in a more controlled environment (LAN or intranet where the bandwidth issue isn't as severe, nor are the visibility concerns) it can be a reasonable approach.

\$\endgroup\$
4
  • 2
    \$\begingroup\$ Amazing, you answered a full minute before me, but still reference my answer! +1 \$\endgroup\$ – MichaelHouse Jul 20 '13 at 16:32
  • 1
    \$\begingroup\$ "Another answer has been posted, click to view" is a useful feature. :D \$\endgroup\$ – user1430 Jul 20 '13 at 16:33
  • \$\begingroup\$ But serializing makes the payload way bigger right? \$\endgroup\$ – Basaa Jul 20 '13 at 20:18
  • 1
    \$\begingroup\$ No; you can in fact often create a smaller payload this way. Consider, for example, the integer. How many bytes does it take to represent "12345" as an ASCII string? Five, assuming you don't need a null terminator. But that value (and many others) easily fits into a four-byte integer. You do need to include some information about how to decode the serialized binary blob, but this can be as minimal as a byte that indicates the packet structure type, which which you can derive the rest of the size information. \$\endgroup\$ – user1430 Jul 20 '13 at 20:52
7
\$\begingroup\$

When serializing data, it's best not to rely on special characters for data separation. Instead, simply let the receiver know how much they need to read to complete the data. Like:

PacketID [ByteLengthOfNextVariable NextVariableBytes]

Then the receiver knows how much of the packet to read before moving on to the next variable. Ideally, you'd have some type information in there as well, but it depends on your use case.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks, that would be the solution. Josh however convinced me to serialize my data. +1. \$\endgroup\$ – Basaa Jul 20 '13 at 19:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.