2011-08-11 25 views
0

我現在完全困惑。.NET異步服務器接收數據沒有明顯的原因

編輯:好的,沒關係。 Python套接字現在也開始做。編輯2:呃,不太確定這是否會導致CPU使用率過高,但是隨機的東西是。有沒有一種有效的方法來找出導致使用量峯值的原因?這個項目有點大,有各種線程。

我有一個異步服務器,它偵聽並等待傳入​​連接,然後使它們保持活動狀態,並等待套接字刷新並提供服務器數據。只有當用戶想要關閉套接字時才關閉。

但是,每當我讓一個套接字&數據流保持連接狀態時,它就會開始發生故障,並開始在無限循環中發送空數據......它可能需要15秒到超過一分鐘的時間,然後纔開始行動。如果我長時間放過真的,它開始導致真正的高CPU使用率。

除了高CPU使用率外,奇怪的是,一切都按原樣運行;郵件發送&收到罰款。

這是我讀的回調函數:

protected void ReadCallback(IAsyncResult ar) 
    { 
     StateObject state = (StateObject)ar.AsyncState; 
     Socket handler = state.SocketHandle; 

     try 
     { 
      int bytesRead = (state.BytesRead += handler.EndReceive(ar)), offset = 0; 
      string line = m_Encoder.GetString(state.Buffer, 0, bytesRead); 
      if (state.Buddy != null) 
       Console.WriteLine(state.Buddy.Address); 
      if (bytesRead > 0) 
      { 
       Console.WriteLine("!!!"); 
       /* A complete request? */ 
       if (line.EndsWith("\n") || line.EndsWith("\x00")) 
       { 
        string[] lines = line.Split('\n'); // ... *facepalm* 
        foreach (string ln in lines) 
         this.MessageReceieved(ln, state); 

        state.Buffer = new byte[StateObject.BUFFER_SIZE]; 
        state.BytesRead = 0; // reset 
       } 
       /* Incomplete; resize the array to accommodate more data... */ 
       else 
       { 
        offset = bytesRead; 
        Array.Resize<byte>(ref state.Buffer, bytesRead + StateObject.BUFFER_SIZE); 
       } 
      } 
      if (handler != null && handler.Connected) 
       handler.BeginReceive(state.Buffer, offset, state.Buffer.Length - offset, SocketFlags.None, new AsyncCallback(ReadCallback), state); 

     } 
     catch (SocketException) 
     { 
      if (state.Buddy != null) 
       state.Buddy.Kill(); 
      else 
       handler.Close(); 
     } 
    } 

我知道這是莫名其妙地通過調用BeginReceive造成的,但我不知道該怎麼保持連接。

回答

2

該代碼中沒有任何東西可以使其失效。

雖然我看到一些問題。

連接檢測

無需檢查套接字連接。您可以在收到回調兩種方式檢測斷線:

  1. 零字節由EndReceive
  2. 一個異常被拋出返回。

我建議您在EndReceive之後做的第一件事是檢查返回值並相應地處理斷開連接。它使代碼更清晰。

如果收到0字節,您的代碼將不會執行任何操作。 handler將停止接收,並仍認爲連接已打開。

緩衝區處理

你的緩衝處理是非常inneffecient。不要每次調整緩衝區大小。它會讓你的服務器減慢很多。從開始分配一個大緩衝區。

字符串處理

每次收到東西時不要建立一個字符串。改爲在新行或空之後檢查字節緩衝區內部。然後建立一個字符串,並且只根據需要製作一個字符串。您可能會收到更多字節,只是一條消息(例如一條半消息)

+0

謝謝!我只是添加了一個else來查看是否正在讀取零字節,然後關閉連接(如果沒有任何...),並且似乎已經解決了問題(現在是atleast)! –

相關問題