¿Cómo puedo escaping de mi delimitador de campo en los datos del package de mi juego?

Para mi juego, decidí no encriptar la carga de mi package. En cambio, voy a verificar todo en el server para asegurarme de que el package sea legítimo.

Como no estoy haciendo ningún encryption, la carga bruta de mi package se ve así:

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

Ahora quiero codificar esos arguments, así que si tengo un | en, por ejemplo, un post de chat, todavía puedo manejar mi package. ¿Cómo puedo conseguir esto?

Hay varias maneras de hacer esto. Podría, por ejemplo, tratar || como siendo un literal | y no su separador de campo Si su process actual para decodificar su package implica primero dividirlo en single | tokens, es probable que desee

  • cambia la split para que use una expresión regular con un lookahead negativo para evitar el || o
  • procesar los datos del package de forma lineal en lugar de dividirlos de manera preventiva.

Dicho esto, en cambio, sugeriría que no transmita datos ASCII como sus cargas útiles de packages, sino que los serialice en una representación binaria eficiente (esto no es lo mismo que encriptarlos ). De esta manera, tendrá mucho less problemas de escape de caracteres, porque la estructura de su package de chat (por ejemplo) será de cuatro bytes para indicar la longitud de un post, seguido de n bytes de datos de caracteres que usted sabe que es el post completo .

(Por supuesto, también puede usar la técnica de prefijar de longitud en una carga útil en formatting ASCII, como sugiere Byte56 en su respuesta).

Alternativamente, si va a utilizar datos de carga ASCII para diagnósticos y visibilidad, elija un formatting que ya se conoce para que pueda aprovechar las especificaciones existentes para escapes de caracteres (o mejor aún, bibliotecas de terceros existentes). Realmente no recomiendo los transportes ASCII para los datos que atraviesan Internet público, pero si solo está transmitiendo en un entorno más controlado (LAN o intranet donde el problema de ancho de banda no es tan severo, ni las preocupaciones de visibilidad) puede ser un enfoque razonable.

Al serializar datos, es mejor no confiar en los caracteres especiales para la separación de datos. En cambio, simplemente deje que el receptor sepa cuánto necesitan leer para completar los datos. Me gusta:

 PacketID [ByteLengthOfNextVariable NextVariableBytes] 

Entonces el receptor sabe cuánto del package leer antes de pasar a la siguiente variable. Idealmente, también tendría información de tipo, pero depende de su caso de uso.