【问题标题】:Checking NetworkStream content with StreamReader使用 StreamReader 检查 NetworkStream 内容
【发布时间】:2011-11-01 16:30:23
【问题描述】:

并向所有成员问好。我正在开发一个小型嵌入式数据采集硬件,它定期收集数据并运行一个小型嵌入式网络服务器。如果请求,服务器会回复一个非常基本的 html 页面以及 128 字节 TCP 块中收集的数据。传输数据的大小最大为 64K。

嵌入式 TCP/IP 堆栈非常薄,MCU 不是最快的,所以我希望请求者应用程序有一个进度指示器(进度条或类似的)。由于要传输的数据数组的长度不断变化,服务器应在数据数组的开头插入实际数据长度。请求者应用程序应读取此长度信息并更新进度条的进度。使用以下代码,我可以接收服务器内容,但只有在传输完成后才能访问数据:

        TcpClient msnTcpConn = new TcpClient();
        try
        {
            msnTcpConn.Connect(HostName, 80);

            if (msnTcpConn.Connected)
            {

                string msg = "";

                NetworkStream netStream = msnTcpConn.GetStream();
                System.IO.StreamWriter sw = new System.IO.StreamWriter(netStream);
                System.IO.StreamReader sr = new System.IO.StreamReader(netStream);

                string req = "";
                req += "GET / HTTP/1.0\r\n";
                req += "Host: " + HostName + "\r\n";
                req += "\r\n";

                sw.Write(req);
                sw.Flush();
                numa = 0;
                peek = 0;
                while (sr.Peek()>=0)
                {
                    peek = sr.Peek();
                    numa++;
                    textBox1.Text = Convert.ToString(numa);
                    msg += sr.ReadLine();;
                }                 

                webBrowser1.DocumentText = msg;
                msnTcpConn.Close();
            }
            else
            {
                MessageBox.Show("Not connected.");
            }
        }
        catch (UriFormatException UriExc)
        {
            MessageBox.Show("Error!");
        }  

在上面的代码中,textBox1 仅在退出循环时才在 while 循环中刷新。因此,我无法及时检查接收到的数据以提取更新进度指示器所需的数据大小。我是 .NET 网络的初学者,所以也许有更好的方法来做这件事,所以任何提示或帮助将不胜感激。谢谢。

【问题讨论】:

    标签: c# .net stream embedded tcpclient


    【解决方案1】:

    这是一个线程问题。在 UI 线程上执行的代码完成之前,UI 不会更新。您需要将从 NetworkStream 读取的代码移动到另一个线程。您需要确保写入 TextBox 的代码在 UI 线程上执行此操作。如果这是一个 WinForms 应用程序,您可以使用 BeginInvoke 执行此操作。

    【讨论】:

    • 我也想过线程,但我不完全理解循环的行为:当它从流中读取一些内容时 (sr.Peek()>=0) 它会更新“peek”变量,它也会增加 'numa' 变量,但不会更新 textBox1 Text 属性。当这个循环在不同的线程中运行时,它会更新 GUI 线程吗?
    • 为了更新 UI 线程,您需要将该代码放在委托/操作中并将该委托/操作发送到 BeginInvoke
    【解决方案2】:

    针对 OPs cmets 进行了编辑:

    您需要将网络阅读代码移动到后台线程 (System.Threading.Thread),然后通过 Dispatcher.BeginInvoke 调用您的 UI 更新代码。

    【讨论】:

    • textBox1.Text = Convert.ToString(numa);用于显示 while 循环执行了多少次。由于整个“下载”大约需要 4-5 秒才能完成,我应该看到文本框中的数字发生了变化。但是,当 webBrowser1 输出页面时,我只看到初始的“0”和之后的“37”。
    猜你喜欢
    • 2020-02-19
    • 1970-01-01
    • 2021-03-23
    • 1970-01-01
    • 1970-01-01
    • 2012-02-26
    • 1970-01-01
    • 2017-07-11
    • 2011-10-03
    相关资源
    最近更新 更多