首页 新闻 会员 周边

关于C#的异步Socket问题

0
悬赏园豆:100 [已关闭问题] 关闭于 2012-05-01 16:07

客户端是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);

}

 

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

另外服务端如何将接收的数据进行解析,而且不影响数据的接收?

bei0305的主页 bei0305 | 初学一级 | 园豆:97
提问于:2011-12-02 21:23
< >
分享
所有回答(3)
0

lock(this.queue)改为lock(自己定义一个对象),你测试下看看

On- The-Way | 园豆:238 (菜鸟二级) | 2011-12-05 16:57

多谢回帖,今天把处理时间打印了一下,因为我读是一个线程,取也是一个线程,所以把lock去掉了,发现问题依旧,pop和push的处理时间均为0.00x毫秒,然后把pop去掉,处理速度就ok了。自己认为可能Queue的pop和push内部实现互相有影响。

现在改为一直push,定时器10秒一次,new一个新的QueueB,将QueueA作为参数传入QueueB的构造函数,然后Clear原来的QueueA,这样貌似是解决了问题,明天还要再测试一下。

支持(0) 反对(0) bei0305 | 园豆:97 (初学一级) | 2011-12-05 18:39
0

byte[] s = this.queue.Pop();

  if(s != null)

  {

    解析

    ...

  }  

  Thread.Sleep(100); 这里 你如果改成如果队列为空了的话 那么 解析线程就休眠 然后io端的线程放入队列的时候 在让解析线程继续工作 这么做的话 会不会好一些 因为whle(true)...

傻瓜力量大 | 园豆:260 (菜鸟二级) | 2011-12-06 11:23

判断队列空的操作,取Queue.Count也是要耗时的,和Push、Pop操作耗时同数量级

支持(0) 反对(0) bei0305 | 园豆:97 (初学一级) | 2011-12-06 12:53

@bei0305:  呵呵 后来我自己也根绝你的这个问题我也做了实验试了一下 我觉得还是thread.sleep(100)好一些

支持(0) 反对(0) 傻瓜力量大 | 园豆:260 (菜鸟二级) | 2011-12-07 22:11
0

C#游戏服务器MMRPG交流群:136485198

血海枫 | 园豆:226 (菜鸟二级) | 2012-05-28 11:58
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册