2010-04-06 3 views
5

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

Несколько изворотливых способов могут думать:

  1. есть список и буфер, после того, как буфер заполнен, добавьте его в список и в конце List.toArray(), чтобы получить byte []

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

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

ответ

3

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

+0

Да, это похоже на самый простой и вместе с тем хороший ответ! – Daniel

-1

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

+0

Возможно преобразование его в строку – Daniel

0

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

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

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

+0

Его просто ASCII да, и это очень хорошая идея !!! Зачем другим кодировкам нужна полная сумма, прежде чем она сможет правильно конвертировать? – Daniel

+0

О, потому что если они используют 2 байта на символ, то, если вы получите 7 байт и попытаетесь его преобразовать, возникнут проблемы. Но вы могли бы просто получить 0-6 и буфер 1, не так ли? Бит больше работы, но меньше давления памяти – Daniel

1

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

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 S? Ну, если вы хотите отлаживать, вы можете захотеть, чтобы освободить соединение TCP, прежде чем принимать свое время, глядя на полученных байтов).

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

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