2010-09-30 217 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