TcpClient читает данные и заполняет массив - PullRequest
0 голосов
/ 18 апреля 2011

В настоящее время находится в процессе написания некоторого кода сокета TCP и запускается небольшая проблема.

В основном меня смущает следующая пара строк кода.

NetworkStream clientStream = tcpClient.GetStream();
List<Byte> fullMessage = new List<Byte>();

Byte[] message = new Byte[4096];
Byte[] currentMessage = new Byte[4096];
Int32 bytesRead = 0;

if (clientStream.CanRead)
{
    do
    {
        bytesRead = clientStream.Read(message, 0, 4096);

        Array.Resize<Byte>(ref currentMessage, bytesRead);
        Array.Copy(message, currentMessage, bytesRead);

        fullMessage.AddRange(currentMessage);

    } while (clientStream.DataAvailable);
}

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

То, как я обрабатываю ответ, считается разумным решениемили есть лучший способ?(IE: создание массива нового размера на основе значения bytesRead)

Ответы [ 2 ]

1 голос
/ 18 апреля 2011

Использовать поток памяти:

NetworkStream clientStream = tcpClient.GetStream();
MemoryStream messageStream = new MemoryStream();
byte[] inbuffer = new byte[65535];

if (clientStream.CanRead)
{
    do
    {
        var bytesRead = clientStream.Read(inbuffer, 0, buffer.Length);
        messageStream.Write(inbuffer, 0, bytesRead);
    } while (clientStream.DataAvailable);
}

messageStream.Position = 0;
var completeMessage = new byte[messageStream.Length];
messageStream.Write(completeMessage, 0, messageStream.Length);
1 голос
/ 18 апреля 2011

Если вы знаете, что сообщение не будет превышать 4096 байт, вы можете написать что-то вроде этого:

int totalBytesRead = 0;
int bytesRead;
while ((bytesRead = clientStream.Read(message, totalBytesRead, message.Length - totalBytesRead)) !=0)
{
    totalBytesRead += bytesRead;
}

totalBytesRead используется для указания clientStream.Read, куда поместить копируемые данные.

clientStream.Read возвращает 0, если нет доступных данных.

Обратите внимание, что при такой настройке вы не можете прочитать более message.Length байтов. Если ваши пакеты могут быть больше, то я предлагаю увеличить ваш буфер. Я не рекомендовал бы постоянно изменять размер массива, потому что это приведет к фрагментации кучи большого объекта (если сообщения станут больше 80 КБ), и в какой-то момент вам придется установить максимальный размер сообщения, даже если вы обрабатываете "произвольно большие" сообщения.

...