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

如何在C#中按包读取TCP数据包?解决Unity接收Matlab数据拼接问题

Fixing TCP Packet Sticking Between MATLAB and Unity

Hey there! That packet concatenation issue you're seeing is totally normal for TCP—it's a stream-based protocol, not message-based, so it groups small packets together for efficiency, or holds onto data if the receiver isn't reading fast enough. Let's fix this by implementing proper packet framing so Unity can reliably read individual "a" or "b" messages.

Here are two straightforward, reliable methods to solve this:


Method 1: Use a Delimiter to Mark Packet Boundaries

The simplest approach is to add a unique delimiter (like a newline \n) after each "a" or "b" in your MATLAB sends. Unity will then buffer incoming data and split it at the delimiter to get individual packets.

Unity C# Implementation

using System.Text;
using UnityEngine;

public class TCPClient : MonoBehaviour
{
    private string _receiveBuffer = "";
    private const string PacketDelimiter = "\n";
    // Assign your target object in the Inspector
    public GameObject targetObject;
    // Your coherence variable, now properly updated
    private string coherence;

    // This method gets called when new data arrives from TCP
    private void OnDataReceived(byte[] data, int bytesRead)
    {
        // Convert incoming bytes to string and add to buffer
        _receiveBuffer += Encoding.ASCII.GetString(data, 0, bytesRead);

        // Process all complete packets in the buffer
        while (_receiveBuffer.Contains(PacketDelimiter))
        {
            int delimiterIndex = _receiveBuffer.IndexOf(PacketDelimiter);
            // Extract the full, single packet (exclude the delimiter)
            string fullPacket = _receiveBuffer.Substring(0, delimiterIndex);
            // Trim the buffer to remove the processed packet
            _receiveBuffer = _receiveBuffer.Substring(delimiterIndex + PacketDelimiter.Length);

            // Handle the packet
            ProcessCoherencePacket(fullPacket);
        }
    }

    private void ProcessCoherencePacket(string packet)
    {
        coherence = packet;
        Debug.Log($"Received valid coherence value: {coherence}");

        // Update object color based on the received value
        Renderer objectRenderer = targetObject.GetComponent<Renderer>();
        if (coherence == "a")
        {
            objectRenderer.material.color = Color.red;
        }
        else if (coherence == "b")
        {
            objectRenderer.material.color = Color.blue;
        }
    }

    // Rest of your TCP connection code (Connect, Listen, etc.) goes here
}

MATLAB Implementation

Add the delimiter to each send call:

% Assuming 'tcpObj' is your established tcpclient connection
send(tcpObj, 'a\n', 'ASCII'); % Send "a" plus newline delimiter
send(tcpObj, 'b\n', 'ASCII'); % Send "b" plus newline delimiter

Method 2: Fixed-Length Packets

Since your messages are always exactly 1 character (1 byte in ASCII), you can configure Unity to read exactly 1 byte at a time. This works great for fixed-size messages.

Unity C# Implementation

using System.Text;
using System.Collections.Generic;
using UnityEngine;

public class TCPClient : MonoBehaviour
{
    private List<byte> _receiveBuffer = new List<byte>();
    private const int PacketSize = 1; // Each packet is 1 byte
    public GameObject targetObject;
    private string coherence;

    private void OnDataReceived(byte[] data, int bytesRead)
    {
        // Add incoming bytes to buffer
        _receiveBuffer.AddRange(data[0..bytesRead]);

        // Process all complete fixed-size packets
        while (_receiveBuffer.Count >= PacketSize)
        {
            // Extract exactly 1 byte for the packet
            byte[] packetBytes = _receiveBuffer.GetRange(0, PacketSize).ToArray();
            // Remove processed bytes from buffer
            _receiveBuffer.RemoveRange(0, PacketSize);

            // Convert to string and handle
            string packet = Encoding.ASCII.GetString(packetBytes);
            ProcessCoherencePacket(packet);
        }
    }

    // Reuse the same ProcessCoherencePacket method from Method 1 here
    private void ProcessCoherencePacket(string packet)
    {
        coherence = packet;
        Debug.Log($"Received valid coherence value: {coherence}");

        Renderer objectRenderer = targetObject.GetComponent<Renderer>();
        if (coherence == "a")
        {
            objectRenderer.material.color = Color.red;
        }
        else if (coherence == "b")
        {
            objectRenderer.material.color = Color.blue;
        }
    }

    // Rest of your TCP connection code goes here
}

MATLAB Implementation

Just send the single character directly (no delimiter needed):

send(tcpObj, 'a', 'ASCII');
send(tcpObj, 'b', 'ASCII');

Key Notes

  • Keep encoding consistent: Use ASCII (or UTF-8) in both MATLAB and Unity to avoid string conversion errors.
  • Buffer management: Make sure you're trimming the buffer after processing packets to prevent memory bloat over time.
  • Scalability: If you ever need to send longer messages later, the delimiter method is more flexible—just pick a delimiter that won't appear in your actual data (e.g., \r\n or a unique sequence like ###END###).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:00:43