客户端是Linux下C编写服务器端由Windows 2003 Server下C#编写服务端使用SocketAsyncEventArgs参数进行建立连接和收发数据在SocketAsyncEventArgs参数Completed事件绑定的方法中进行收到数据处理处理步骤如下1、将收到的args.Buffer中的BytesTransferred数量的字节Push入队列Queue<byte[]>中,然后调用socket.ReceiveAsync()继续进行异步接收2、线程a循环从队列中Pop出byte[]数据进行解析3、队列的Pop和Push操作均有lock 问题如下:1、百兆网络环境下,服务端的接收流量大概在0M到80~90MB/s之间波动剧烈2、客户端会出现发送缓冲区满的现象,也就是说,服务端处理过慢3、如果接收线程中的处理去掉Push操作,客户端发送正常,服务端也接收正常,网络流量大概在80~100MB/s波动 从现象看,是因为Push操作导致服务端处理速度变慢,从而客户端出现发送缓冲区满的现象 Push操作lock(this.queue){queue.EnQueue(byte[] s)}操作。Pop操作lock(this.queue){if(this.queue.Count > 0){return this.queue.DeQueue()}else{return null}} 解析数据线程a的操作while(true){  byte[] s = this.queue.Pop();  if(s != null)  {    解析    ...  }    Thread.Sleep(100);} 请问一下服务端要怎样才能接收的过来,不至于让客户端阻塞?另外服务端如何将接收的数据进行解析,而且不影响数据的接收?

解决方案 »

  1.   

    “去掉Push操作”,其实就等于你去掉了服务器端几乎所有随后的处理操作,因为没有数据也就无法测试到那些深度的代码。可见你的服务器整体上有问题,而不是什么Push有问题。基本上来说,结构选择不合理从而不应该加lock的时候滥用lock,不应该创建线程的时候滥用线程,应该用线程的时候只用顺序处理,这些都是原因。
      

  2.   

    另外很显然,如果一个所谓客户端只是一味地write数据,它从来不与服务器交互地发送一块块数据,那么它也未免太随便了。
      

  3.   

    谢谢sp1234是这样的1、只有Push操作和Pop操作有lock,没有滥用lock
    2、接收数据的线程是系统在SocketAsyncEventArgs参数Completed事件引发时候启动的
    3、处理数据的是一个线程
    4、客户端和服务端是有心跳操作的
      

  4.   

    楼主有易理解的SocketAsyncEventArgs的示例吗,分享一下