gpt4 book ai didi

C# NetworkStream 数据丢失

转载 作者:行者123 更新时间:2023-11-30 20:24:06 30 4
gpt4 key购买 nike

我目前正在从事一个网络项目,我在其中制定了一个二进制协议(protocol)。我的数据包看起来像这样:[1 字节类型][2 字节索引][2 字节长度][长度字节数据]

这是我接收数据包的代码:

NetworkStream clientStream= Client.GetStream();
while (Client.Connected)
{
Thread.Sleep(10);
try
{
if (clientStream.DataAvailable)
{
byte[] infobuffer = new byte[5];
int inforead = clientStream.Read(infobuffer, 0, 5);
if (inforead < 5) { continue; }
byte[] rawclient = new byte[2];
Array.Copy(infobuffer, 1, rawclient, 0, 2);
PacketType type = (PacketType)Convert.ToSByte(infobuffer[0]);
int clientIndex = BitConverter.ToInt16(rawclient, 0);
int readLength = BitConverter.ToInt16(infobuffer, 3);
byte[] readbuffer = new byte[readLength];
int count_read = clientStream.Read(readbuffer, 0, readLength);
byte[] read_data = new byte[count_read];
Array.Copy(readbuffer, read_data, count_read);

HandleData(read_data, type, clientIndex);
}
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("[E] " + ex.GetType().ToString());
Console.ResetColor();
break;
}
}

嗯,一切正常...只要我在 127.0.0.1 上运行它。一旦我尝试长距离测试它,数据包就会以某种方式丢失,并且我在将第一个字节转换为 PacketType 的行上遇到溢出异常。此外,如果我尝试将其他值转换为 int16,我会得到非常奇怪的值。

我假设流在到达服务器的途中以某种方式丢失了一些字节,但这是真的吗?或者这只是我在代码某处的一个小错误?

编辑:我现在编辑了代码,现在它一直读取到它的 5 个字节。但是我仍然在长距离上遇到同样的异常......

NetworkStream clientStream = Client.GetStream();
while (Client.Connected)
{
Thread.Sleep(10);
try
{
if (clientStream.DataAvailable)
{
int totalread = 0;
byte[] infobuffer = new byte[5];
while (totalread < 5)
{
int inforead = clientStream.Read(infobuffer, totalread, 5 - totalread);
if (inforead == 0)
{ break; }
totalread += inforead;
}
byte[] rawclient = new byte[2];
Array.Copy(infobuffer, 1, rawclient, 0, 2);
PacketType type = (PacketType)Convert.ToSByte(infobuffer[0]);
int clientIndex = BitConverter.ToInt16(rawclient, 0);
int readLength = BitConverter.ToInt16(infobuffer, 3);
byte[] readbuffer = new byte[readLength];
int count_read = clientStream.Read(readbuffer, 0, readLength);
byte[] read_data = new byte[count_read];
Array.Copy(readbuffer, read_data, count_read);

HandleData(read_data, type, clientIndex);
}
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("[E] " + ex.GetType().ToString());
Console.ResetColor();
break;
}
}

PacketType 是一个枚举:

public enum PacketType
{
AddressSocks5 = 0,
Status = 1,
Data = 2,
Disconnect = 3,
AddressSocks4 = 4
}

最佳答案

你在这里做错了很多事情......这么多错误......甚至从哪里开始......

第一次网络投票?真的吗?在当今时代,这只是进行网络事件的一种幼稚方式。但我不会对此喋喋不休。

其次,使用这种类型的协议(protocol),很容易“不同步”,一旦发生,就无法恢复同步。这通常是通过某种“成帧协议(protocol)”来完成的,它提供了一个唯一的字节序列,您可以使用它来指示帧的开始和结束,这样如果您发现自己不同步,您可以读取数据直到您得到恢复同步。是的,您会丢失数据,但如果不同步,您就已经丢失了数据。

第三,你在这里并没有真正做任何大事,所以我无耻地从这里窃取了“ReadWholeArray”代码,它不是最有效的,但它有效并且那里还有其他代码可能有帮助:

http://www.yoda.arachsys.com/csharp/readbinary.html

注意:您没有提及如何在另一侧序列化长度、类型和索引值。所以使用 BitConverter 可能是错误的,这取决于它是如何完成的。

if (clientStream.DataAvailable)
{
byte[] data = new byte[5];
// if it can't read all 5 bytes, it throws an exception
ReadWholeArray(clientStream, data);
PacketType type = (PacketType)Convert.ToSByte(data[0]);
int clientIndex = BitConverter.ToInt16(data, 1);
int readLength = BitConverter.ToInt16(data, 3);

byte[] rawdata = new byte[readLength];
ReadWholeArray(clientStream, rawdata);
HandleData(rawdata, type, clientIndex);
}

/// <summary>
/// Reads data into a complete array, throwing an EndOfStreamException
/// if the stream runs out of data first, or if an IOException
/// naturally occurs.
/// </summary>
/// <param name="stream">The stream to read data from</param>
/// <param name="data">The array to read bytes into. The array
/// will be completely filled from the stream, so an appropriate
/// size must be given.</param>
public static void ReadWholeArray (Stream stream, byte[] data)
{
int offset=0;
int remaining = data.Length;
while (remaining > 0)
{
int read = stream.Read(data, offset, remaining);
if (read <= 0)
throw new EndOfStreamException
(String.Format("End of stream reached with {0} bytes left to read", remaining));
remaining -= read;
offset += read;
}
}

关于C# NetworkStream 数据丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27460113/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com