我正在将传感器数据从android设备发送到C#中的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
    

    10-07 19:16
    查看更多