关于C#的异步Socket服务端客户端速率匹配问题

bei0305 2011-12-03 09:25:52
客户端是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);

}



请问一下服务端要怎样才能接收的过来,不至于让客户端阻塞?

另外服务端如何将接收的数据进行解析,而且不影响数据的接收?
...全文
161 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
另外很显然,如果一个所谓客户端只是一味地write数据,它从来不与服务器交互地发送一块块数据,那么它也未免太随便了。
  • 打赏
  • 举报
回复
“去掉Push操作”,其实就等于你去掉了服务器端几乎所有随后的处理操作,因为没有数据也就无法测试到那些深度的代码。可见你的服务器整体上有问题,而不是什么Push有问题。

基本上来说,结构选择不合理从而不应该加lock的时候滥用lock,不应该创建线程的时候滥用线程,应该用线程的时候只用顺序处理,这些都是原因。
绿领巾童鞋 2011-12-03
  • 打赏
  • 举报
回复
楼主有易理解的SocketAsyncEventArgs的示例吗,分享一下
bei0305 2011-12-03
  • 打赏
  • 举报
回复
谢谢sp1234

是这样的

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

111,125

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧