- Я общаюсь с сервером, который нуждается в нуле строке завершающейся
- Как я могу сделать это бойко в C#?
ответ
Я предполагаю, что вы реализуете какой-то двоичный протокол, если строки имеют нулевое завершение. Вы используете 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
.
Вы добавляете нулевой символ в конец строки. Строки .NET могут содержать нулевые символы.
Нравится программа "\ 0"? –
Я думаю, что он предлагает «char c = new char()», который создаст точку unicode «U + 0000». –
Строки уже завершены нулем. Хотя сама строка не содержит нулевой символ, нулевой символ всегда следует за строкой в памяти.
Однако строки в .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 массив все заполнены нулями, когда создается, так что вам не нужно на самом деле установить дополнительный байт до нуля.)
Исправлена небольшая опечатка. Я не слишком доволен распределением двойного буфера лично. Вы можете обойти это. Опять же, строки вряд ли будут огромными или очень большими. – Thorarin
«Null terminated» обычно означает «завершение с первым нулем». Строки .NET не могут считаться завершающими нулями, если вы также допускаете, что строка .NET может содержать один или несколько нулевых символов и все же не заканчиваться –
«Строки уже завершены с нулем. Хотя сама строка не содержит нулевой символ, нулевой символ всегда следует за строкой в памяти ". Я никогда не слышал об этом раньше и не видел никакой информации об этом в документах MSDN. Не могли бы вы опубликовать источник? – Juliet
Я думаю, что разумный способ - это просто сделать это.
string str = "An example string" + Char.MinValue; // Add null terminator.
Затем преобразуйте его в байты для отправки на сервер.
byte[] buffer = ASCIIEncoding.ASCII.GetBytes(str);
Конечно, какая кодировка вы используете, зависит от того, какую кодировку ожидает сервер.
char.MinValue - это реальный способ C# –
Это, безусловно, самый простой (и самый надежный) способ, который я нашел. Это должен быть принятый ответ. – jhmckimm
Я бы предложил использовать base.Write (this._encoding.GetBytes (new char [] {'\ u0000'})) вместо этого, чтобы закодировать нулевой ограничитель. UTF-16 по умолчанию - 2 байта и ожидает в конце двух 0-байтов. – toong
Добавить значение с помощью «\ 0» (если оно уже не заканчивается): 'if (! Value.EndsWith (" \ 0 ")) value + =" \ 0 ";' поэтому делает решение ** кодировкой -независимый ** (вам не нужно беспокоиться о количестве нулей). – marchewek