2010-05-08 2 views
11
  • Я общаюсь с сервером, который нуждается в нуле строке завершающейся
  • Как я могу сделать это бойко в C#?

ответ

13

Я предполагаю, что вы реализуете какой-то двоичный протокол, если строки имеют нулевое завершение. Вы используете BinaryWriter?

По умолчанию BinaryWriter записывает строки как префиксы длины. Вы можете изменить это поведение:

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

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

Тогда вы можете просто написать любую строку, как это:

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

Вам может понадобиться настроить _encoding немного, в зависимости от ваших потребностей.

Вы можете, разумеется, расширить класс с особыми потребностями в отношении других типов данных, которые вам могут потребоваться для переноса, сохраняя при этом фактическую реализацию протокола чистой и чистой. Вам, вероятно, также понадобятся ваши собственные (очень похожие) BinaryReader.

+1

Я бы предложил использовать base.Write (this._encoding.GetBytes (new char [] {'\ u0000'})) вместо этого, чтобы закодировать нулевой ограничитель. UTF-16 по умолчанию - 2 байта и ожидает в конце двух 0-байтов. – toong

+0

Добавить значение с помощью «\ 0» (если оно уже не заканчивается): 'if (! Value.EndsWith (" \ 0 ")) value + =" \ 0 ";' поэтому делает решение ** кодировкой -независимый ** (вам не нужно беспокоиться о количестве нулей). – marchewek

5

Вы добавляете нулевой символ в конец строки. Строки .NET могут содержать нулевые символы.

+1

Нравится программа "\ 0"? –

+1

Я думаю, что он предлагает «char c = new char()», который создаст точку unicode «U + 0000». –

8

Строки уже завершены нулем. Хотя сама строка не содержит нулевой символ, нулевой символ всегда следует за строкой в ​​памяти.

Однако строки в .NET являются unicode, поэтому они хранятся в памяти UTF-16/UCS-2, и сервер может ожидать другую кодировку, обычно 8-битную кодировку. Тогда вы должны закодировать строку в массив байтов и поместить нулевой байт в конце:

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

(zdata массив все заполнены нулями, когда создается, так что вам не нужно на самом деле установить дополнительный байт до нуля.)

+0

Исправлена ​​небольшая опечатка. Я не слишком доволен распределением двойного буфера лично. Вы можете обойти это. Опять же, строки вряд ли будут огромными или очень большими. – Thorarin

+5

«Null terminated» обычно означает «завершение с первым нулем». Строки .NET не могут считаться завершающими нулями, если вы также допускаете, что строка .NET может содержать один или несколько нулевых символов и все же не заканчиваться –

+0

«Строки уже завершены с нулем. Хотя сама строка не содержит нулевой символ, нулевой символ всегда следует за строкой в ​​памяти ". Я никогда не слышал об этом раньше и не видел никакой информации об этом в документах MSDN. Не могли бы вы опубликовать источник? – Juliet

30

Я думаю, что разумный способ - это просто сделать это.

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

Затем преобразуйте его в байты для отправки на сервер.

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

Конечно, какая кодировка вы используете, зависит от того, какую кодировку ожидает сервер.

+4

char.MinValue - это реальный способ C# –

+0

Это, безусловно, самый простой (и самый надежный) способ, который я нашел. Это должен быть принятый ответ. – jhmckimm

 Смежные вопросы

  • Нет связанных вопросов^_^