0

我正在创建一个基于套接字的遥测应用程序,我使用两个无线电调制解调器来发送/接收数据,一个应用程序通过调制解调器 1 发送数据,另一个程序通过调制解调器 2 获取数据,我的发送间隔是一秒,似乎接收器应用程序(服务器)正在使用大部分 CPU 和 RAM 资源(99% 的 cpu 使用率!)并且它的内存使用量稳步增加!这样几分钟后我的程序几乎停止响应并且我的数据根本不正确,因此无法解析数据,似乎我的程序收到了发送数据的多个副本,我的原始数据包约为70字节,但经过一些秒它的大小增加,我认为我的接收缓冲区已满并且数据与以前的数据混合,我正在寻找一些建议,这是我在服务器程序中的接收处理程序:

private void DataReceive()
    {
        handler.ReceiveBufferSize = 100;

        try
        {
            byte[] bytes = new byte[100];
            int byteRec;
            while (true)
            {
                timer1.Enabled = true;
                while (true)
                {
                    byteRec = handler.Receive(bytes);
                    if (byteRec > 0)
                    {
                        data = System.Text.Encoding.UTF8.GetString(bytes, 0, byteRec);
                        break;
                    }
                }

                if (data.Length >= 30)
                {
                    if (data.Substring(0, 1) == "#")//pasrse data, correct!
                    {
                        label27.Text = data.Length.ToString();
                        textBox1.Text = data;
                        string a = data.Substring(1);

                        string[] b = a.Split('-');

                        SetControlPropertyThreadSafe(lblTotal, "Text", b[0]);
                        SetControlPropertyThreadSafe(lblFlow, "Text", b[1]);

                        float real_analog2 = (1 - (((20 - float.Parse(b[4])) / (20 - 4)))) * Analog2_Max;
                        if (real_analog2 < 0)
                            real_analog2 = 0;
                        SetControlPropertyThreadSafe(lblAnalog, "Text", real_analog2.ToString());

                        if (b[2] == "1")//off
                            SetControlPropertyThreadSafe(lblMotion, "Text", "off");
                        else if (b[2] == "0")//on
                            SetControlPropertyThreadSafe(lblMotion, "Text", "on");

                        if (b[3] == "1")//off
                            SetControlPropertyThreadSafe(lblMotion2, "Text", "off");
                        else if (b[3] == "0")//on
                            SetControlPropertyThreadSafe(lblMotion2, "Text", "on");

                        SetControlPropertyThreadSafe(lblV1, "Text", b[5]);
                        SetControlPropertyThreadSafe(lblV2, "Text", b[6]);
                        SetControlPropertyThreadSafe(lblV3, "Text", b[7]);
                        SetControlPropertyThreadSafe(lblI1, "Text", b[8]);
                        SetControlPropertyThreadSafe(lblI2, "Text", b[9]);
                        SetControlPropertyThreadSafe(lblI3, "Text", b[10]);
                        SetControlPropertyThreadSafe(lblLevelPercent, "Text", b[11]);
                        SetControlPropertyThreadSafe(lblLevelValue, "Text", b[12]);
                    }
                }
                FillLstMsg(data);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
4

2 回答 2

2

当你做一段时间(真)时,你应该总是Thread.Sleep(x)在那里添加一个。这样可以防止循环成为紧密循环并消耗您的 CPU。

你只需要睡几毫秒就够了。

至于内存消耗,我怀疑你可能在某个地方有泄漏。还要考虑当 CPU 非常繁忙时,.NET 框架将推迟垃圾收集,直到它不会对系统产生影响(即 CPU 使用率较低),或者系统内存不足。

可能是当您添加 Thread.Sleep 时,会发生垃圾收集并且内存使用会保持稳定。

于 2012-04-30T10:48:14.817 回答
2

基本上我认为你的方法是错误的。

你怎么能说发送接收的数据大小?第一个数据包消息何时结束而另一个数据包消息何时开始?你知道你的完整信息包有多大吗?

这些是您在从另一端接收数据包时应该仔细验证的一些问题。

我在 TCP 实现中继承的一个常见做法是首先发送即将到来的数据包大小,然后根据该数据包大小处理消息。这将为您提供极大的灵活性来创建更健壮的 TCP 实现。如果你这样做,你就可以一个接一个地发送尽可能多的数据包而不会崩溃。

我还看到您将演示代码与接收数据代码搞砸了。您应该创建一个单独的类库来处理所有 TCP 通信操作,并将接收到的数据扔到消费者应用程序中。

Nito Async 库对我来说是一个很好的起点。你可以看到他在做什么,虽然太先进的技术和真正好的代码,你可以抓住基本的想法。

从他博客中这个漂亮的解释开始,然后在 codeplex 中捕获代码。我现在看到他更新了一些东西,所以你可以把他所有的精力都用在你的代码上,或者如果它适合你的话,甚至是他的 :)

http://nitoprograms.blogspot.com/2009/04/tcpip-net-sockets-faq.html

快乐阅读!

于 2012-04-30T13:01:57.797 回答