0

ソケットベースのテレメトリアプリを作成しています。2つの無線モデムを使用してデータを送受信します。1つのアプリはモデム1を介してデータを送信し、もう1つのプログラムはモデム2を介してデータを取得します。送信間隔は1秒のようです。レシーバーアプリ(サーバー)は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

while(true)を実行するときは、常にそこにを追加する必要Thread.Sleep(x)があります。これにより、ループがタイトなループになり、CPUを消費するのを防ぎます。

数ミリ秒だけ寝る必要があります。それで十分です。

メモリー消費量については、どこかでリークが発生しているのではないかと思います。また、CPUが非常にビジー状態の場合、ガベージコレクションは、システムに影響がなくなるまで(つまり、CPU使用率が低くなるまで)、またはシステムのメモリが不足するまで、.NETFrameworkによって延期されることを考慮してください。

Thread.Sleepを追加すると、ガベージコレクションが発生し、メモリ使用量が一定に保たれる可能性があります。

于 2012-04-30T10:48:14.817 に答える
2

基本的にあなたのアプローチは間違っていると思います。

送受信されたデータサイズはどのように言えますか?最初のパケットメッセージが終了し、別のパケットメッセージが開始するのはいつですか。フルパケットメッセージの大きさを知っていますか?

これらは、もう一方の端からパケットを受信するときに注意深く検証する必要があるいくつかの問題です。

TCP実装で継承した一般的な方法は、最初に着信するパケットサイズを送信し、次にそのパケットサイズに基づいてメッセージを処理することです。これにより、柔軟性が高くなり、より堅牢なTCP実装が作成されます。これを行うと、クラッシュすることなく、必要な数のパケットを次々に送信できます。

また、受信データコードでプレゼンテーションコードを台無しにしたようです。すべてのTCP通信操作を処理するための個別のクラスライブラリを作成し、受信したデータをコンシューマアプリケーションにスローする必要があります。

NitoAsyncライブラリは私にとって非常に良い出発点でした。彼が何をしているのかを見ることができますが、そこには高度な技術と本当に優れたコードがありますが、基本的な考え方を理解することができます。

彼のブログでこの美しい説明から始めて、codeplexでコードをキャッチしてください。彼がいくつかのものを更新したので、あなたは彼のすべての努力をあなたのコードに、あるいはそれがあなたに合っていれば彼にさえも得ることができるようになりました:)

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

幸せな読書!

于 2012-04-30T13:01:57.797 に答える