2010-05-08 9 views
11
  • me estoy comunicando con un servidor que necesita cadena terminada en nulo
  • ¿Cómo puedo hacer esto inteligentemente en C#?

Respuesta

13

Supongo que está implementando algún tipo de protocolo binario, si las cadenas tienen terminación nula. ¿Estás usando un BinaryWriter?

El valor predeterminado BinaryWriter escribe cadenas como prefijo de longitud. Puede cambiar ese comportamiento:

class MyBinaryWriter : BinaryWriter 
{ 
    private Encoding _encoding = Encoding.Default; 

    public override void Write(string value) 
    { 
     byte[] buffer = _encoding.GetBytes(value); 
     Write(buffer); 
     Write((byte)0); 
    } 
} 

a continuación, puedes escribir cualquier cadena como esta:

using (MyBinaryWriter writer = new MyBinaryWriter(myStream)) 
{ 
    writer.Write("Some string"); 
} 

Es posible que tenga que ajustar el bit _encoding, dependiendo de sus necesidades.

Puede, por supuesto, expandir la clase con necesidades específicas para otros tipos de datos que pueda necesitar transferir, manteniendo su implementación real del protocolo agradable y limpia. Probablemente también necesite su propia (muy similar) BinaryReader.

+1

Sugeriría utilizar base.Write (this._encoding.GetBytes (new char [] {'\ u0000'})) en su lugar, para codificar el terminador nulo. El UTF-16 predeterminado tiene 2 bytes y espera dos bytes de 0 al final. – toong

+0

Añadir valor con "\ 0" (si no termina con él): 'if (! Value.EndsWith (" \ 0 ")) value + =" \ 0 ";' por lo tanto, hacer la solución ** de codificación -independiente ** (no tiene que preocuparse por la cantidad de ceros). – marchewek

5

Agrega un carácter nulo al final de la cadena. Las cadenas .NET pueden contener caracteres nulos.

+1

Me gusta este "\ 0"? –

+1

Creo que está sugiriendo 'char c = new char()', que creará el punto Unicode 'U + 0000'. –

8

Las cadenas ya están cerradas. Aunque la cadena en sí misma no contiene un carácter nulo, un carácter nulo siempre sigue la cadena en la memoria.

Sin embargo, las cadenas en .NET son unicode, por lo que se almacenan como UTF-16/UCS-2 en la memoria, y el servidor puede esperar una codificación diferente, generalmente una codificación de 8 bits. Entonces tendría que codificar la cadena en una matriz de bytes y colocar un byte cero al final:

byte[] data = Encoding.Default.GetBytes(theString); 
byte[] zdata = new byte[data.Length + 1]; 
data.CopyTo(zdata, 0); 

(La matriz se ZDATA toda llena de ceros cuando se crea, por lo que no tiene que fijar la realidad byte extra a cero.)

+0

Se corrigió un error tipográfico menor. No estoy muy contento con la asignación de doble buffer personalmente. Puedes soslayar eso. Por otra parte, no es probable que las cuerdas sean de volumen enorme o muy alto. – Thorarin

+5

"Nulo terminado" generalmente significa "terminando en el primer nulo". Las cadenas .NET no se pueden considerar terminadas en nulo si también se permite que una cadena .NET pueda contener uno o más caracteres nulos y aún no terminar –

+0

"Las cadenas ya están terminadas. Aunque la cadena en sí no contiene un nulo carácter, un carácter nulo siempre sigue la cadena en la memoria ". Nunca escuché esto antes y no vi información sobre esto en los documentos de MSDN. ¿Podrías publicar una fuente? – Juliet

30

Creo que la manera inteligente es hacerlo simplemente.

string str = "An example string" + Char.MinValue; // Add null terminator. 

luego convertirlo en bytes a enviar al servidor.

byte[] buffer = ASCIIEncoding.ASCII.GetBytes(str); 

Por supuesto, la codificación que utiliza depende de qué codificación espera el servidor.

+4

char.MinValue es la verdadera forma de C# –

+0

Esta es la forma más simple (y más confiable) que he encontrado hasta ahora. Esta debería ser la respuesta aceptada. – jhmckimm

Cuestiones relacionadas