我有一个TCP套接字应用程序,我必须读取几种类型的回复,即缓冲区的最大大小8192,一些回复被分成更多的数据包。
目前我收到回复44的成员列表,所以我必须能够处理拆分数据包的第一个想法是定义一个流输出端来存储输入数据,直到它完成一个bool和当前大小变量。
一旦它点击回复44,它将检查extraList是真还是假,如果是,则表示它是对传入成员列表的初始请求。
如果数据包的4个初始字节大于bytes.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();
}
}
}
}
}
}
}
答案 0 :(得分:1)
在简短地阅读代码时,引人注目的是神奇数字(9,44)和非常深的嵌套。 用具有良好命名的常量替换数字,并将代码的某些部分作为方法移出。
如果他们被使用过的局部变量严密扭曲 - 可能所有这些方法都值得一劳永逸地转移到工人阶级 - 来阅读消息。因此,局部变量成为类字段,方法对于重构不会那么灵活。
对于我来说,MemberList(...)也是一个糟糕的方法名称。使它成为描述正在做什么方法的动词。
答案 1 :(得分:1)
要合并不在一起的字节,可以使用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);