gpt4 book ai didi

c# - TCP 服务器未正确读取固定大小的消息

转载 作者:可可西里 更新时间:2023-11-01 02:35:48 24 4
gpt4 key购买 nike

我正在使用 C# 将传感器数据从 Android 设备发送到 TCP 服务器。 android 客户端以 32 字节的固定大小块发送数据。

在服务器中,我读取了数据,预计它会以完整的形式出现,但由于 TCP 是一种流协议(protocol),一些消息到达服务器时分为两部分。我知道这一点,因为我可以使用名为 SocketSniff 的软件观看它。

问题是我不知道如何在我的服务器上处理它。

我找到的所有示例都使用 NetworkStream.Read(),在这个方法中,我必须传递一个字节数组来存储读取的数据、一个偏移量和要读取的字节数。这个字节数组必须有一个已知的大小,在我的例子中是 32。

我不知道到达我的服务器的邮件的实际大小,但可能是以下情况之一。

  • 如果接收到的数据大小是 32 字节,则一切正常。

  • 如果接收到的数据大小大于 32 字节,我认为我正在丢失数据。

  • 如果接收到的数据大小小于 32 个字节,比方说 20 个字节,这些字节将存储在我的数组中,并且数组的最后 12 个字节保留为零值。由于我可能真的收到了一些零,所以无法知道我真正收到的大小,所以我无法将它与应该在下一次读取中出现的剩余数据合并。

我处理接收的代码如下:

    int buffer = 32;
...
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();

byte[] message = new byte[buffer];
int bytesRead;

while (true)
{
bytesRead = 0;

try
{
bytesRead = clientStream.Read(message, 0, message.Length);
}
catch
{
break;
}

if (bytesRead == 0)
{
// Connection closed
break;
}

SensorData sensorData = ProcessTcpPacket(message);
}
tcpClient.Close();
}

有什么方法可以知道我在套接字中接收到的数据的大小吗?

最佳答案

是的,您有 bytesRead 变量 - 它保存从流中读取的字节数。您将最多阅读 message.Length 字节,但您可能会阅读更少。

请注意,如果有更多字节可用,您不会通过只读取 message.Length 字节来丢失它们。相反,它们将在您下次从流中阅读时可用。

你需要做的是像这样添加另一个 while 循环:

int messageRead = 0;

while(messageRead < message.Length)
{
int bytesRead = clientStream.Read(message, messageRead, message.Length - messageRead);
messageRead += bytesRead;
if(bytesRead==0)
return; // The socket was closed
}
// Here you have a full message

关于c# - TCP 服务器未正确读取固定大小的消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9640157/

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