You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过TCP在Node.js服务器与Unity C#客户端间传输UInt16类型数据?及传输效率咨询

Great question! Let's break this down step by step:

1. Is transferring UInt16 directly more efficient than string transmission?

Absolutely, yes. Here's why:

  • Smaller data size: A UInt16 is a fixed 2-byte value, whereas a string representation of a UInt16 can take up to 5 bytes (e.g., "65535" is 5 ASCII characters). For frequent sensor value updates, this adds up to less bandwidth usage over time.
  • Faster parsing: Converting a string back to a number involves string parsing logic with more overhead than directly interpreting binary bytes. Direct binary transmission cuts out this step, making both sending and receiving faster, especially with high-frequency updates.

2. How to implement UInt16 transmission and client-side conversion?

The core idea is to send the UInt16 as raw binary bytes instead of a string, and parse those bytes correctly on the Unity side. We need to pay close attention to byte order (endianness) to ensure consistency between Node.js and Unity.

Modified Node.js Code

Instead of converting the value to a string, we'll create a 2-byte Buffer representing the UInt16. We'll use little-endian (common on x86 systems) to match Unity's default behavior on Windows, but we'll note how to adjust for big-endian if needed:

server.on('connection', function(socket) {
    console.log('A new connection has been established.');

    if (sensor != null){
        sensor.on("change", value => {
            // Ensure the value stays within UInt16's 0-65535 range
            const uint16Value = value & 0xFFFF; 
            // Create a little-endian 2-byte buffer
            const buffer = Buffer.alloc(2);
            buffer.writeUInt16LE(uint16Value, 0);
            socket.write(buffer);
        });
    }

    socket.on('data', function(chunk) {
        console.log(`Data received from client: ${chunk.toString()}`);
    });

    socket.on('end', function() {
        console.log('Closing connection with the client');
    });

    socket.on('error', function(err) {
        console.log(`Error: ${err}`);
    });
});

If you need big-endian instead, replace writeUInt16LE with writeUInt16BE.

Modified Unity C# Code

On the Unity side, we need to read the 2-byte binary data and convert it back to a UInt16. Since TCP is a stream protocol, we have to handle cases where we might receive partial bytes (e.g., one byte at a time). Here's a robust implementation:

TcpClient socketConnection;
byte[] receiveBuffer = new byte[2]; // UInt16 is always 2 bytes
int bytesReceived = 0;

void Start()
{
    socketConnection = new TcpClient("localhost", 8080);
    StartCoroutine(ReceiveDataCoroutine());
}

IEnumerator ReceiveDataCoroutine()
{
    using (NetworkStream stream = socketConnection.GetStream())
    {
        while (socketConnection.Connected)
        {
            // Reset count for each new UInt16 value
            bytesReceived = 0;
            
            // Keep reading until we have all 2 required bytes
            while (bytesReceived < 2)
            {
                int read = stream.Read(receiveBuffer, bytesReceived, 2 - bytesReceived);
                if (read == 0)
                {
                    Debug.Log("Connection closed by server");
                    yield break;
                }
                bytesReceived += read;
            }

            // Convert bytes to UInt16 (little-endian, matches Node.js code)
            // If using big-endian in Node.js, uncomment this line: Array.Reverse(receiveBuffer);
            ushort value = BitConverter.ToUInt16(receiveBuffer, 0);
            Debug.Log($"Received UInt16 value: {value}");
        }
    }
}

Key Notes on Endianness:

  • If you used writeUInt16BE in Node.js, add Array.Reverse(receiveBuffer); before calling BitConverter.ToUInt16 to match big-endian order.
  • While BitConverter.IsLittleEndian can check the system's native endianness for cross-platform compatibility, explicitly using the same endianness on both sides is more reliable.

Why your original attempt failed?

When you tried direct UInt16 transmission, you were likely running into one of these issues:

  • Partial byte reads: TCP doesn't guarantee whole message delivery, so you might have been trying to parse incomplete 2-byte chunks.
  • Incorrect byte order: Mismatched endianness between Node.js and Unity would produce garbled values.
  • Wrong conversion method: Convert.ToUInt16(incomingData) doesn't work for 2-byte arrays—it expects a string or single byte, not raw binary.

内容的提问来源于stack exchange,提问作者Lee Probert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 04:19:09