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

TCP客户端无法接收Arduino以太网服务器的全部数据

解决C#仅读取Arduino以太网服务器第一行数据的问题

问题根源

嘿,我一眼就看出问题出在哪了——你的C#代码只调用了一次stream.Read()!网络流的数据不一定会一次性全部传输到本地,第一次读取大概率只拿到了Arduino发送的第一行内容,剩下的data2到data5还在流里等着被读取呢。而且stream.Read()的返回值是实际读取到的字节数,只有当它返回0时,才说明流里已经没有更多数据了。

修复后的C#代码

我给你调整了代码逻辑,用循环持续读取流中的数据,直到所有内容都被获取,同时用using语句自动管理资源(不用手动关闭stream和client,更安全也更简洁):

void ReceiveData()
{
    // 使用using自动释放TcpClient和NetworkStream资源,避免内存泄漏
    using (TcpClient client = new TcpClient("192.168.1.85", 64000))
    using (NetworkStream stream = client.GetStream())
    {
        Byte[] dataReceive = new Byte[256];
        StringBuilder responseData = new StringBuilder(); // 用StringBuilder拼接字符串更高效
        Int32 bytesRead;

        // 循环读取,直到流中没有更多数据(bytesRead返回0)
        while ((bytesRead = stream.Read(dataReceive, 0, dataReceive.Length)) > 0)
        {
            responseData.Append(System.Text.Encoding.ASCII.GetString(dataReceive, 0, bytesRead));
        }

        // 注意:如果ReceiveData是在后台线程调用的,必须跨线程更新UI
        if (txtReceive.InvokeRequired)
        {
            txtReceive.Invoke(new Action(() => txtReceive.Text += responseData.ToString()));
        }
        else
        {
            txtReceive.Text += responseData.ToString();
        }
    }
}

额外说明

  • 用StringBuilder代替string拼接:因为string是不可变类型,多次拼接会产生大量临时对象,StringBuilder在处理多次字符串拼接时性能更优。
  • 跨线程UI更新:如果你的ReceiveData是通过后台线程(比如Timer、Task)调用的,直接修改txtReceive会触发跨线程异常,所以加了InvokeRequired的判断来确保在UI线程更新控件。
  • Arduino端代码没问题:它确实发送了所有5行数据,问题完全出在C#的读取逻辑上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:18:13