我实际上是从Matlab发送数据来更新UNITY场景: - Matlab使用TCP协议向UNITY发送“a”或“b” - UNITY接收“a”或“b”,并更新颜色基于此字符的对象
我在UNITY中更新了名为“coherence”的变量时遇到了问题。当脚本运行时,来自MATLAB的数据包正在连接。例如,如果我在日志文件中打印“coherence”,它看起来像“aaaaababbbbbbbbaaaaabbbbbbababababbbbaaababbaabbbaba”。我想要的是,我的最后一个数据包是唯一要读取和打印的数据包(例如,“coherence”是“a”,然后是“b”,然后是“b”,然后是“a”等等,而不是“a”然后“ab”然后“abb”然后“abba”...)。
请问我的代码中有什么问题可以告诉我吗?指令“ReadToEnd”是否正常?
非常感谢您的投入,
的Yannick
// Use this for initialization of TCP Server
TcpListener listener;
String coherence;
// Initialization of the script
void Start()
{
_renderer = GetComponent();
listener = new TcpListener(55001);
listener.Start();
print("is listening");
}
void Update()
{
if (!listener.Pending())
{
}
else
{
print("socket comes");
TcpClient client = listener.AcceptTcpClient();
NetworkStream ns = client.GetStream();
StreamReader reader = new StreamReader(ns);
coherence = reader.ReadToEnd();
print(coherence);
}
if (coherence == "a")
{
colorFin = Color.green;
}
else if (coherence == "b")
{
colorFin = Color.yellow;
}
}
答案 0 :(得分:1)
与UDP不同,TCP在逻辑上是流API,而不是数据包API。虽然在某些低级别可能来访问原始数据包,但几乎所有消费者 API都将其作为流公开,并不保证接收将匹配发送方式原始数据包布局。相反,保证的是:相同的字节,相同的顺序。这意味着你需要实现某种类型的框架"协议。对于基于文本的协议,这通常意味着简单:行 - 即在每个完整消息之后添加CR / LF / CRLF。对于二进制协议,这通常意味着每个完整消息之前的某种长度前缀。
请注意ReadToEnd()
仅在您希望所有数据一次出现时(而不是通过两个端点之间的x / y / x / y / x / y对话)才可用;虽然我个人建议在使用套接字时完全避免使用StreamReader
,并且只使用原始套接字API或流API。像ReadToEnd
这样的代码很容易永远阻止。如果这是一个只需要单个套接字的客户端,那可能没问题,但对于服务器(有很多套接字),这很糟糕:恶意客户端可以通过简单地发送"Hi"
而不是断开连接来永久锁定线程 。这永远不会满足ReadToEnd
。