延时拼包机制让c# socket实现海量数据包广播吞吐
之前已经简单的测试了c# socket的数据吞吐处理能力,结果虽然比较理想;但以这样的数据包处理量在某些场景下是远远不够用的,在某些应用场景中每秒要处理的数据包不是1,2W个可能几W,上10W或更多的数据包吞吐。在一个游戏场景中同场景存在100用户,每个用户的变更都会通知其他199的用户,如果每个用户平均每秒变更3次,那服务端每秒接收转发的数据包就是100x100x3=3w个。如果是200个用户同场景,那所每秒所面对的处理包会是200x200x3=12W个,想c# socket提供这么密集的IO处理是不太可能的事情,即使是可以那也要很不错的硬件支撑。
从软件上去解决这问题那只能选择减少IO操作,之前的测试表明SendAsync这相的IO操作是非常损耗资源。既然问题已经知道发生在什么地方,我们可以采用减少SendAsync又不影响交互性来达到这一点。大家知道网络访问存在一个延时的系数,通过在可接受的延时区间可以把发送的A的N个数据包打包到一个buffer里,然后进行一次SendAsync操作,原本在这一时间段时有100个消息包发给A,那可以打包成一个这样SendAsync的操作就可以从原来的100次变成一次;那些这节省是相当可观的,当然这个设计尽可能根据当前调度情况来确定,调度空闲的情况下不合拼,调度存在压力的时候进行一个合拼处理。
以下是针对这个设计的测试结果:
测试硬件:
server:Core2 4300 1.8G 2G win2003
client1:Core i7 Q740 1.7G 4G win764
client2:P4 2.4G 1G WIN2003
测试逻辑:
每个client程序开启50个连接,每个连接秒产生3次座标变化告诉服务端,由服务端专发给其他client.
定期为每个client发送ping包,检测服务器处理和回发的延时时间。
数据结构:
public class ChangePostion:IMessage { public int X { get; set; } public int Y { get; set; } public string ID { get; set; } public void Save(BufferWriter writer) { writer.Write(X); writer.Write(Y); writer.WriteBlock(ID); } public void Load(BufferReader reader) { X = reader.ReadInt32(); Y = reader.ReadInt32(); ID = reader.ReadBlock(); } private static Random ran = new Random(); public static ChangePostion GetPoint() { ChangePostion cp = new ChangePostion(); cp.X = ran.Next(1, 399); cp.Y = ran.Next(1, 399); return cp; } } public class Ping : IMessage { public string ID { get; set; } public DateTime Ticks { get; set; } public void Save(BufferWriter writer) { writer.WriteBlock(ID); } public void Load(BufferReader reader) { ID = reader.ReadBlock(); } }
100人同场景测试
服务端程序情况:
client情况
测试情况来看每个client每秒接收1.6w个数据包,两个client接收大概3.2W个数据包,服务端的下行带宽是2MB/秒,每秒处理3.2W对象写入缓冲发送。
200人同场景测试
服务器端情况
客户端情况
测试情况来看每个client每秒接收3.2w个数据包,4个client接收大概13W个数据包,服务端的下行带宽是8MB/秒,每秒处理13W对象写入缓冲发送
注意
当使用了拼包的时候就要考虑一下Socket.NoDelay是否需要开启,还有client的ReceiveBufferSize是否需要加大,在测试过程中当存在大量数据包接收的时候有个别client连接接收到的数据不正常,之于这个问题是.net的内置缓冲问题还是程序设计上的缺陷还在追查中(查明原因后会编写文章讲述问题情况)。
下载测试程序
BeetleTest20111127.rar (935.91 kb)
跑测试程序最好把client分布在不同机器上
通过上面的测试可以让想用C# Socket做应用的朋友更进一步了解它的处理能力到底怎样。对于想要源码的朋友就不需要问了,对于些问题的分析可以访问:www.henryfan.net