2010-09-30 219 views
0

首先我是socket編程中的n00b。所以我決定在局域網TCP服務器編寫簡單的數據來處理進來的數據 我的服務器代碼是TCP服務器客戶端問題

private void HandleClientComm(object client) 
{ 

    TcpClient tcpClient = (TcpClient)client; 
    NetworkStream clientStream = tcpClient.GetStream(); 
    clientStream.ReadTimeout = 10; 
    int size = 4096 * 1000; 
    byte[] message = new byte[size]; 
    byte[] All = new byte[0]; 
    int bytesRead; 
    string error = ""; 
    lock (this) 
    { 
     while (true) 
     { 
      All = new byte[0]; 
      while (true) 
      { 
       bytesRead = 0; 
       try 
       { 
        bytesRead = clientStream.Read(message, 0, size); 
        All = AddBArrays(All, message, bytesRead); 
       } 
       catch 
       { 
        break; 
       } 

       if (bytesRead == 0) 
       { 
        break; 
       } 

      } 
      if (All.Length > 0) 
      { 
       Message m = (Message)Tools.ByteArrayToObject(All); 
       OnRecived(new RecivedArgs("localhost", (Message)Tools.ByteArrayToObject(All))); 
      } 
     } 
     tcpClient.Close(); 
    } 
} 
byte[] AddBArrays(byte[] ar1, byte[] ar2, int read) 
{ 
    byte[] concat = new byte[ar1.Length + read]; 
    if (ar1.Length != 0) 
     System.Buffer.BlockCopy(ar1, 0, concat, 0, ar1.Length); 
    System.Buffer.BlockCopy(ar2, 0, concat, ar1.Length, read); 
    return concat; 
} 

它的工作原理,但有一些問題。它接收文件大於100 mbs或smthng,並且如果我經常發送數據間隔< 800,則數據丟失。我應該如何改進我的代碼?大文件問題並不重要,主要問題是快速數據發送中的數據丟失。 TNX求助

好吧,我現在建議

private void HandleClientComm(object client) 
{ 

    TcpClient tcpClient = (TcpClient)client; 
    NetworkStream clientStream = tcpClient.GetStream(); 
    clientStream.ReadTimeout = 10; 
    int size = 4096 * 1000; 
    List<byte> Test = new List<byte>(); 
    byte[] message = new byte[size]; 
    byte[] All = new byte[0]; 
    int bytesRead; 
    while (true) 
    { 
     //All = new byte[0]; 
     while (true) 
     { 
      bytesRead = 0; 
      try 
      { 
       bytesRead = clientStream.Read(message, 0, size); 
       for (int i = 0; i < bytesRead; i++) 
       { 
        Test.Add(message[i]); 
       } 
      } 
      catch 
      { 
       break; 
      } 

      if (bytesRead == 0) 
      { 
       break; 
      } 
     } 
     if (Test.Count > 0) 
     { 
      Message m = (Message)Tools.ByteArrayToObject(Test.ToArray()); 
      OnRecived(new RecivedArgs("localhost", m)); 
      Test = new List<byte>(); 
     } 
    } 
    tcpClient.Close(); 

} 

更新的代碼,但問題仍然存在

編輯 - >大文件問題修復它只是一個「System.OutOfMemoryException的」但它沒有拋出錯誤。

+0

是多線程的HandleClientComm方法... IE瀏覽器...是多線程進來? – 2010-09-30 14:40:34

+0

爲每個客戶一個威脅。但我已經用一個客戶端測試了它 – Woland 2010-10-01 05:51:03

回答

0

好的,我解決了這個問題。 我簡單地發送到很多數據來快速,所以數據丟失是不可避免的。

我的優化代碼是

private void HandleClientComm(object client) 
{ 
    TcpClient tcpClient = (TcpClient)client; 
    NetworkStream clientStream = tcpClient.GetStream(); 
    int size = 1; 
    byte[] message = new byte[1]; 
    int bytesRead; 
    while (true) 
    { 
     bytesRead = 0; 
     if (clientStream.DataAvailable) 
      bytesRead = clientStream.Read(message, 0, 1); 
     if (bytesRead > 0) 
     { 
      OnRecived(new RecivedArgs("tick", null)); 
     } 
     Thread.Sleep(1); 
    } 
} 

我已經測試間隔低至1毫秒,無數據丟失:) 感謝您的幫助

0
  • 全部字節數組您應該更改爲List<byte>。您現在正在創建像瘋狂的實例。 GC可能比需要的工作量多得多。這可能會減慢它的速度,以至於跟不上。

沒有真正涉及到插座:

  • 製作大小const
  • NEVER鎖定this。創建一個可以鎖定的私人字段。事實上,我甚至不認爲你需要在這裏鎖定。
  • 刪除錯誤字符串。
+0

*使用AddRange()添加到列表 Bryan 2010-09-30 13:49:22

+0

做到了,但仍然是同樣的問題 – Woland 2010-10-01 06:04:19

+0

也addrange複製到列表的所有消息,但大部分時間它只填充250字節的數據只是零,我認爲這是一個很大的內存浪費。 – Woland 2010-10-01 06:10:35