Как написать огромную строку в NetworkStream? - PullRequest
0 голосов
/ 27 июля 2010

Из Интернета я получил способ прочитать огромную строку из NetworkStream.

 static NetworkStream ns = null;
 static StringBuilder sb = null;
 static byte[] buffer = null;
 static int position = 0;
 //.......................................
 //other codes skipped for simplicity
 //....................................... 
 private static string Read()
 {
        if (ns.CanRead)
        {
            sb.Clear();
            position = 0;
            while (ns.DataAvailable)
            {
                position = ns.Read(buffer, 0, buffer.Length);
                sb.Append(Encoding.Unicode.GetString(buffer, 0, position));
            }

            return sb.ToString().Trim();
        }
        else
        {
            return null;
        }
 }

Однако я не могу найти пример, как записать огромную строку в NetworkStream.

Существует ли "симметричный" шаблон для записи, как мы делаем для чтения?

Заранее спасибо.

1 Ответ

5 голосов
/ 27 июля 2010

Это чтение кода опасно неправильно во многих отношениях:

  • Использование статических переменных таким образом безнадежно непригодно для многопоточных задач.(Надеюсь, это просто из-за того, что вы упростили его ...)
  • Он никогда не инициализирует переменные ненулевыми значениями - опять же, надеюсь, это не настоящий код
  • Он использует DataAvailable свойство определять, когда это должно быть «сделано» - это невероятно опасно, так как это означает, что если пакет задерживается в потоке, вы можете прочитать вдвое меньше данных, чем вы ожидали, чтобы
  • Он всегда использует Encoding.Unicode, который редко является лучшим выбором кодировки
  • Предполагается, что он всегда будет читать целое количество символов.Что если один символ разделен между чтениями?Вот для чего нужны Encoder / Decoder классы ... но вам все равно не нужно их здесь использовать - см. Ниже.

Я настоятельно рекомендую вам обернуть NetworkStream в StreamReader для чтения и StreamWriter для записи.Вот для чего они.Затем вы можете прочитать строку за раз, или просто буфер char[], или до конца потока (что означает «до тех пор, пока сокет не будет закрыт»).Это хорошо для текстового протокола.

Если у вас есть протокол, который смешивает текстовые и двоичные данные, жизнь становится намного сложнее.Лично мне нравятся протоколы с сообщениями с префиксом длины - таким образом вы можете читать только данные, для которых вы предназначены, а затем выполнять любое преобразование, какое захотите.

В любом случае, я надеюсь, что это случайноевыбор мыслей помогает ... если вам нужна более подробная помощь, укажите подробности того, какой протокол вы используете.

...