从套接字合并拆分的字节以供进一步使用



我有一个TCP套接字应用程序,在那里我必须读取几种类型的回复,即缓冲区的最大大小8192。一些回复被拆分成更多的数据包。

目前,我在回复44中收到了一个成员列表,所以我必须能够处理分裂的数据包的第一个想法是定义一个流,以存储传入的数据,直到它与bool和当前大小变量一起完成。

一旦它到达回复44,它将检查extraList是真是假,如果是假,则意味着它是对传入成员列表的初始请求。

如果数据包的4个初始字节大于字节。Legth是8192,它将触发extraList为true,并将初始数据填充到我之前设置的缓冲区中,使总数据包大小保持原样。

由于extraList已被触发并变为true,因此数据包读取将落入其中,直到数据完成,然后将其设置回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();
                        }
                    }
                }
            }
        }
    }
}

在简要阅读代码时,会发现幻数(9,44)和非常深的嵌套。用命名良好的常量替换数字,并将代码的某些部分作为方法移出。

如果它们被使用的局部变量紧紧地扭曲了——可能所有这些方法都值得转移到具有单一责任的工人类——来读取消息。因此,局部变量就变成了类字段,方法对重构就不会那么灵活了。

另外,MemberList(…)对我来说是一个不好的方法名称。请将其作为一个动词来描述方法正在执行的操作。

要合并不在一起的字节,可以使用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);

最新更新