Объединить разделенные байты из сокета для дальнейшего использования? - PullRequest
0 голосов
/ 16 июня 2011

У меня есть приложение с сокетом TCP, где я должен прочитать несколько типов ответов, так как максимальный размер буфера 8192, некоторые ответы разделены на несколько пакетов.

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

Как только он нажмет ответ 44, он проверит, является ли extraList истиной или ложью, если ложь, это означает, что это начальный запрос к списку входящих участников.

Если 4 начальных байта пакета больше, чем bytes.Legth, который равен 8192, он вызовет extraList для истины и заполнит начальные данные в буфере, который я ранее установил, с общим размером пакета, так как он является размером .

Так как extraList был запущен и стал истинным, чтение пакета попадет в него до тех пор, пока не будут завершены данные, что затем вернет его в значение false и вызовет функцию MemberList с полным списком.

Хотели бы некоторые советы, предложения и т. Д. Для улучшения этого кода.

int storedCurSize = 0;
MemoryStream stored = null;
bool extraList = false;

while (roomSocket.Connected)
{
    byte[] bytes = new byte[roomSocket.ReceiveBufferSize];
    roomSocket.Receive(bytes);

    MemoryStream bufferReceived = new MemoryStream(bytes, 0, bytes.Length);
    using (var reader = new BinaryReader(bufferReceived))
    {
        int packetSize = (int)reader.ReadInt32() + 9;
        int reply = (int)reader.ReadByte();
        if (reply == 44 || extraList)
        {
            if (!extraList && packetSize <= bytes.Length)
            {
                MemberList(bytes);
            }
            else
            {
                if (!extraList)
                {
                    stored = new MemoryStream(new byte[packetSize], 0, packetSize);
                    stored.Write(bytes, 0, bytes.Length);
                    storedCurSize = bytes.Length;
                    extraList = true;
                }
                else
                {
                    if (storedCurSize < stored.Length)
                    {
                        int storedLeftSize = (int)stored.Length - storedCurSize;
                        stored.Write(bytes, 0, (storedLeftSzie < bytes.Length) ? storedLeftSize : bytes.Length);
                        storedCurSize += (storedLeftSize < bytes.Length) ? storedLeftSize : bytes.Length;
                        if (storedCurSize >= stored.Length)
                        {
                            extraList = false;
                            MemberList(stored.ToArray());
                            stored.Close();
                        }
                    }
                }
            }
        }
    }
}

Ответы [ 2 ]

1 голос
/ 16 июня 2011

Чтобы объединить не объединенные байты, вы можете использовать Buffer.BlockCopy ().

byte[] buf1;
byte[] buf2;
byte[] concatenated = new byte[buf1.Length + buf2.Length];

Buffer.BlockCopy(buf1, 0, concatenated, 0, buf1.Length);
Buffer.BlockCopy(buf2, 0, concatenated, buf1.ength, buf2.Length);
1 голос
/ 16 июня 2011

При кратком чтении кода вспыхивают магические числа (9, 44) и очень глубокая вложенность.Замените числа константами с хорошими именами и удалите некоторые части кода в качестве методов.

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

Также MemberList (...) - плохое имя для метода, как для меня.Сделайте глагол, который опишет, что делает метод.

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