【问题标题】:HoloLens application based on Unity not able to receive TCP data基于 Unity 的 HoloLens 应用程序无法接收 TCP 数据
【发布时间】:2020-09-02 10:17:32
【问题描述】:

我正在开发基于 Unity 的 HoloLens (1) 应用程序。我正在尝试通过 TCP 从基于 Qt 的应用程序 (Windows) 向 HoloLens 发送数据。 Wireshark 显示,我的测试包已被 HoloLens 正确发送和确认。数据以包含消息长度的四个字节开始,紧接着这四个字节开始。在下面的代码中,首先尝试接收四个字节,然后是消息本身。

在客户端应用程序中执行连接和发送数据的代码后,在 HoloLens 上调用StreamSocketListener_ConnectionReceived()。在下一次Update() 调用中,ReadTcpData() 被调用。现在,执行在第一次调用时“停止”

tcpMessageSizeBuffer[tcpMessageSizeBytesRead++] = (byte)stream.ReadByte();

当我尝试越界时,至少调试器会跳出代码。在 catch 块中没有捕获到异常。

如果没有可读取的内容,我期待StreamReaderEndOfStream 属性为假,因此,当它为真时调用ReadByte 时,我会从流中接收到一个有效字节。我不知道这里出了什么问题。任何提示将不胜感激。

using System;
using System.IO;
using UnityEngine;

#if UNITY_WINRT && !UNITY_EDITOR
using Windows.Networking.Sockets;
using Windows.Networking;
using Windows.Networking.Connectivity;
using Windows.Storage.Streams;
using System.Runtime.InteropServices.WindowsRuntime;
#endif

public class NetworkManager : MonoBehaviour
{
    public int tcpPort;

#if UNITY_WINRT && !UNITY_EDITOR
    private StreamSocketListener streamSocketListener;
    private StreamReader tcpStreamReader = null;
    private StreamSocketListenerConnectionReceivedEventArgs connectionArgs;
    private DatagramSocket datagramSocket;
    private MemoryStream pendingDatagramSocketStream;
#endif

    private UInt32 tcpMessageSizeByteCount;
    private UInt32 tcpMessageSizeBytesRead;
    private byte[] tcpMessageSizeBuffer;

    private bool tcpMessageSizeReceived;

    private UInt32 tcpMessageByteCount;
    private UInt32 tcpMessageBytesRead;
    private byte[] tcpMessageBuffer;

    // Use this for initialization
    void Start()
    {
        Application.runInBackground = true;
        ResetTcpConnection();
    }

    public void ResetTcpConnection()
    {
#if UNITY_WINRT && !UNITY_EDITOR
        ResetTcpRead();

        if (streamSocketListener != null)
        {
            tcpStreamReader.Dispose();
            tcpStreamReader = null;
            connectionArgs = null;
            streamSocketListener.Dispose();
            streamSocketListener = null;
        }

        streamSocketListener = new StreamSocketListener();
        streamSocketListener.ConnectionReceived += this.StreamSocketListener_ConnectionReceived;
        streamSocketListener.BindServiceNameAsync(tcpPort.ToString());
#endif
    }

#if UNITY_WINRT && !UNITY_EDITOR
    // Process the client connection.
    private async void StreamSocketListener_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
    {
        connectionArgs = args; // Keep this alive
        tcpStreamReader = new StreamReader(connectionArgs.Socket.InputStream.AsStreamForRead());
    }
#endif

    // Update is called once per frame
    void Update()
    {
#if UNITY_WINRT && !UNITY_EDITOR
        if (tcpStreamReader != null && !tcpStreamReader.EndOfStream)
        {
            Stream stream = tcpStreamReader.BaseStream;
            ReadTcpData(ref stream);
        }
#endif
    }

    private void ResetTcpRead()
    {
        tcpMessageSizeByteCount = sizeof(UInt32);
        tcpMessageSizeBytesRead = 0;
        tcpMessageSizeBuffer = new byte[tcpMessageSizeByteCount];

        tcpMessageSizeReceived = false;

        tcpMessageByteCount = 0;
        tcpMessageBytesRead = 0;
        tcpMessageBuffer = null;
    }

    private void ReadTcpData(ref Stream stream)
    {
        try
        {
            if (!tcpMessageSizeReceived)
            {
#if UNITY_WINRT && !UNITY_EDITOR
                while(tcpMessageSizeBytesRead < tcpMessageSizeByteCount && !tcpStreamReader.EndOfStream)
                {
                    tcpMessageSizeBuffer[tcpMessageSizeBytesRead++] = (byte)stream.ReadByte();
                }

                if(tcpMessageSizeBytesRead == tcpMessageSizeByteCount)
                {
                    tcpMessageByteCount = BitConverter.ToUInt32(tcpMessageSizeBuffer, 0);
                }
#endif

                if (tcpMessageByteCount > 0)
                {
                    tcpMessageBuffer = new byte[tcpMessageByteCount];
                    tcpMessageSizeReceived = true;
                }
            }
            else
            {
                // Read the message
                int bytesToRead = (int)(tcpMessageByteCount - tcpMessageBytesRead);
                bytesToRead = bytesToRead > 10000 ? 10000 : bytesToRead;
                int bytesRead = stream.Read(tcpMessageBuffer, (int)tcpMessageBytesRead, bytesToRead);
                tcpMessageBytesRead += (uint)bytesRead;

                // Did we finish reading the message?
                if (tcpMessageBytesRead >= tcpMessageByteCount)
                {
                    ResetTcpRead();
                }
            }
        }
        catch (Exception e)
        {
            throw e;
        }
    }
}

【问题讨论】:

    标签: unity3d uwp hololens


    【解决方案1】:

    发现问题 - 我必须使用BinaryReader 并替换读取消息长度的代码,例如:

    while(tcpMessageSizeBytesRead < tcpMessageSizeByteCount)
    {
       tcpMessageSizeBuffer[tcpMessageSizeBytesRead++] = (byte)binaryReader.ReadByte();
    }
    

    为了一致性,实际读取消息的部分代码也可以适配为BinaryReader

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-09
      • 2020-09-18
      • 1970-01-01
      • 2014-09-06
      相关资源
      最近更新 更多