2012-04-30 20 views
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); 
     } 
    } 
+1

有什麼特別的原因,你沒有使用NetworkStream(與它的StreamReader讀取它作爲文本)? – harold

+0

我該如何使用NetworkStream?我只想讀取通過無線調制解調器發送的數據 –

+1

非常簡單,只需用socket作爲參數創建一個新的。 – harold

回答

2

基本上我認爲你的方法是錯誤的。

你怎麼能說發送和接收的數據大小? 第一個分組消息何時結束而另一個分組消息何時開始? 你知道你的全部信息包有多大?

這些是您在接收來自另一端的數據包時應仔細驗證的一些問題。

我在TCP實現中繼承的常見做法是首先發送即將到來的包大小,然後根據該包大小處理消息。這將爲您創建更強大的TCP實現提供極大的靈活性。如果你這樣做,你可以發送儘可能多的數據包,你想要一個接一個沒有崩潰。

我也看到你搞砸了接收數據代碼的演示代碼。 您應該創建一個單獨的類庫來處理所有的TCP通信操作,並將接收到的數據扔到消費者應用程序中。

Nito異步庫對我來說是一個非常好的起點。你可以看到他在做什麼,雖然技術過於先進,代碼真的很好,但你可以抓住基本的想法。

從他的博客中的這個美麗的解釋開始,然後在codeplex中捕獲代碼。我現在說,他更新了一些東西看,這樣你就可以得到他的所有努力,你的代碼,甚至是他的,如果它適合你:)

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

快樂閱讀!

+0

謝謝,我知道我的大小,因爲我從我的客戶端發送數據包,它不是固定大小,我使用「 - 」分隔我的數據編號,但有時會有幾個數據包在一起,我不知道如何解析數據!我嘗試你的新想法,我希望它能幫助我 –

+1

首先發送數據包大小,然後根據收到的大小解析下一個數據包。這是常用的技術和正確的方法來做到這一點,其他任何事情都會失敗,正如我所知道的。不要與 - 或任何東西分開。你將有一個小小的時間來正確地解決它,並獲得主要功能始終工作:) –

1

當你做了一段時間(真),你應該總是在那裏添加一個Thread.Sleep(x)。這會阻止循環變成緊密的循環並消耗你的CPU。

你只需要睡幾毫秒,就足夠了。

至於內存消耗,我懷疑你可能有泄漏的地方。還要考慮到,當CPU非常繁忙時,垃圾收集將被.NET框架推遲,直到它不會對系統產生影響(即CPU使用率較低)或系統內存不足。

這可能是因爲當你添加Thread.Sleep時,垃圾回收會發生並且內存使用會保持穩定。

+0

謝謝,幾秒鐘後接收數據的大小會增加多少?我總是希望擁有相同的數據,但是我收到的數據在一段時間後變得越來越大 –

+0

我測試了睡眠和事件,但仍然沒有運氣! –

+1

Socket.Receive已經阻塞(除非有輸入,在這種情況下,循環退出),所以這不是一個嚴格的循環。 – harold