客户端是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);
}
请问一下服务端要怎样才能接收的过来,不至于让客户端阻塞?
另外服务端如何将接收的数据进行解析,而且不影响数据的接收?
lock(this.queue)改为lock(自己定义一个对象),你测试下看看
多谢回帖,今天把处理时间打印了一下,因为我读是一个线程,取也是一个线程,所以把lock去掉了,发现问题依旧,pop和push的处理时间均为0.00x毫秒,然后把pop去掉,处理速度就ok了。自己认为可能Queue的pop和push内部实现互相有影响。
现在改为一直push,定时器10秒一次,new一个新的QueueB,将QueueA作为参数传入QueueB的构造函数,然后Clear原来的QueueA,这样貌似是解决了问题,明天还要再测试一下。
byte[] s = this.queue.Pop();
if(s != null)
{
解析
...
}
Thread.Sleep(100); 这里 你如果改成如果队列为空了的话 那么 解析线程就休眠 然后io端的线程放入队列的时候 在让解析线程继续工作 这么做的话 会不会好一些 因为whle(true)...
判断队列空的操作,取Queue.Count也是要耗时的,和Push、Pop操作耗时同数量级
@bei0305: 呵呵 后来我自己也根绝你的这个问题我也做了实验试了一下 我觉得还是thread.sleep(100)好一些
C#游戏服务器MMRPG交流群:136485198