C # производительность методов получения данных из сокета? - PullRequest
5 голосов
/ 06 апреля 2010

Давайте предположим, что у нас есть простой интернет-сокет, и он будет отправлять 10 мегабайт (потому что я хочу игнорировать проблемы с памятью) случайных данных. Есть ли разница в производительности или метод передовой практики, который следует использовать для получения данных? Окончательные выходные данные должны быть представлены байтом []. Да, я знаю, что запись произвольного количества данных в память - это плохо, и если бы я загружал большой файл, я бы не делал это так. Но ради аргумента давайте проигнорируем это и предположим, что это небольшой объем данных. Я также понимаю, что узким местом здесь, вероятно, является не управление памятью, а получение сокетов. Я просто хочу знать, какой будет самый эффективный способ получения данных.

Можно подумать о нескольких хитрых путях:

  1. Иметь List и буфер, после заполнения буфера добавьте его в список и в конец list.ToArray (), чтобы получить байт []

  2. Записать буфер в поток памяти, после того как он завершит построение байта [] потока. Длина и прочитать все в него, чтобы получить вывод байта [].

Есть ли более эффективный / лучший способ сделать это?

Ответы [ 4 ]

3 голосов
/ 06 апреля 2010

Просто напишите в MemoryStream и затем вызовите ToArray - это поможет вам создать байтовый массив подходящего размера. По сути, в любом случае List<byte> будет выглядеть, но использование MemoryStream будет намного проще.

1 голос
/ 31 марта 2011

Что ж, ответ Джона Скита великолепен (как обычно), но кода нет, поэтому вот моя интерпретация. (Работал хорошо для меня.)

using (var mem = new MemoryStream())
{
    using (var tcp = new TcpClient())
    {
        tcp.Connect(new IPEndPoint(IPAddress.Parse("192.0.0.192"), 8880));
        tcp.GetStream().CopyTo(mem);
    }
    var bytes = mem.ToArray();
}

(Почему бы не объединить два using с? Что ж, если вы хотите отладить, вы можете разорвать соединение tcp, прежде чем потратить время на просмотр полученных байтов.)

Этот код будет принимать несколько пакетов и агрегировать их данные, к вашему сведению. Так что это отличный способ просто получить все данные TCP, отправленные во время соединения.

0 голосов
/ 07 апреля 2010

Какая кодировка ваших данных? это просто ASCII или что-то еще, например UTF-8 / Unicode?

если это обычный ASCII, вы можете просто выделить StringBuilder () необходимого размера (получить размер из заголовка ContentLength ответа) и продолжить добавлять свои данные в компоновщик после преобразования их в строку с помощью Encoding.ASCII.

Если это Unicode / UTF8, то у вас есть проблема - вы не можете просто вызвать Encoding..GetString (buffer, 0, bytesRead) для прочитанных байтов, потому что bytesRead может не представлять собой фрагмент логической строки в этой кодировке. В этом случае вам нужно будет буферизовать все тело объекта в память (или файл), затем прочитать этот файл и декодировать его, используя кодировку.

0 голосов
/ 06 апреля 2010

Вы можете записать в поток памяти, а затем использовать потоковый ридер или что-то подобное для получения данных. Что вы делаете с данными? Я спрашиваю, потому что было бы более эффективно с точки зрения памяти записывать входящие данные в файл или таблицу базы данных при получении данных, а не сохранять все содержимое в памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...