从套接字合并拆分的字节以供进一步使用
本文关键字:进一步 字节 套接字 合并 拆分 | 更新日期: 2023-09-27 17:59:20
我有一个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);