首页 > 范文大全 > 正文

Socket数据缓冲队列设计

开篇:润墨网以专业的文秘视角,为您筛选了一篇Socket数据缓冲队列设计范文,如需获取更多写作素材,在线客服老师一对一协助。欢迎您的阅读与分享!

摘要:随着计算机技术的飞速发展,我所开发socket数据缓冲队列设计向人们展现了它美好的应用前景。从实际应用问题的需要出发,该设计环境采用了C#语言和Visual Studio开发工具。

关键词:数据缓冲队列;设计;C#

中图分类号TP39 文献标识码A 文章编号 1674-6708(2012)66-0197-02

1 开发环境介绍

C#是微软公司的一种新的面向对象编程语言。它是微软公司研究员Anders Hejlsberg的最新成果。作为.NET开发平台中最重要的一门语言,越来越受到广大程序员的青睐。由C和C++衍生出来的,继承了C和C++强大功能,同时去掉了一些复杂特性。C#综合了VB简单的可视化操作和C++的高运行效率,以其强大的操作能力、创新的语言特性和便捷的面向组件编程的支持成为.NET开发的首选语言。

Visual Studio是微软公司推出的目前最流行的Windows平台应用程序开发环境,可以用来创建 Windows平台下的应用程序和网络应用程序,也可以用来创建网络服务、智能设备应用程序和 Office插件。

2 应用场景:数据转发

在很多消息发送服务中都涉及到数据转发,常见的IM工具,比如QQ、MSN等等,企业用的特定数据转发服务,比如GPS实时定位等。在数据量小的情况下一般不会有什么问题,但如果数据大,又对实时性要求比较高,如果处理不好则会出现性能问题。

对转发服务一般性要求:

1)同时接收多个来源的数据连接;

2)同时连接多个目标的数据连接;

3)实时转发;

4)保证数据转发顺序与接收顺序一致;

5)本地保留数据副本

首先,对于实时转发,就要求在收到数据后立刻写入目标客户端连接,然后保存副本到本地数据库。在客户端连接正常的情况下,一般不会有什么问题,但internet网络的畅通性一般情况下是无法保证的,如果一旦在收到源数据后,而对应客户端又暂时连接不上,就会出现需要暂存数据的要求。

对于暂存数据,一般情况下是保存到本地数据库中,等客户端连接后再一条一条查询出对应数据后发送,这样可以实现此要求,但如果某个客户端断线很长时间,在本地暂存数据达到上千上万记录,如果这样处理,势必会影响发送速度,甚至可能会出现发送速度比接收速度还慢,那就会数据越积累越多,永远发送不完。

除了上述问题,还有另一种情况,就是在客户端频繁短时间断线,这种情况会出现对暂存数据库的频繁更新,对性能影响也很大。

对于前面的问题,我们现在可设计一个内存队列池,每个客户端如果需要暂存数据,则先在此内存队列池中创建一个内存队列,将暂存数据保存到对应队列中,如果暂存数据量大于指定的某个值(根据内存大小及实际需要指定),则将后续暂存数据持久到暂存数据库,这样,对于长时间断线的客户端产生的大量暂存数据的性能有一定缓解,对于频繁短时间断线的客户端所产生的频繁更新暂存数据库的情况则可以完全避免。

3 设计思想

队列池设计,分为队列 和 池。对于池的设计比较简单,主要实现包括:

1)内部队列缓存集合;

2)初始化(指定队列数据最大大小、加载上次队列关闭时持久的队列);

3)数据入队(调用客户端对应队列的入队);

4)数据出队(调用客户端对应队列的出队);

5)关闭(持久化队列)

队列的设计,主要包括:

1)初始化(实例化一个简单的先进现出队列、加载上次队列关闭时持久的数据)

2)数据入队

先同步队列锁,防止入队和出队的线程并发操作,然后判断暂存数据是否超过队列大小限制,如果超过则持久化到数据库中(附加功能,发送电子邮件到指定邮箱,提醒数据出现问题),否则添加到队列。

3)数据出队

先同步队列锁,防止入队和出队的线程并发操作,然后判断当前队列容量是否等于队列最大容量,如果是,则有可能暂存数据库中有暂存数据,删除之并对数据出队,否则直接对数据出队。

4)关闭(持久化队列中数据)。

4 实现代码

/// 添加新数据到队列

public void Enqueue(GpsData data)

{lock (((ICollection)queue).SyncRoot)

{ if (queue.Count < queueSize)

{ //添加到队列

queue.Enqueue(data);

if (!string.IsNullOrEmpty(data.Key) && IsSendEMail.Contains(data.Key))

{ IsSendEMail.Remove(data.Key); }}

else

if (!string.IsNullOrEmpty(data.Key) && !IsSendEMail.Contains(data.Key))

{ MailHelper mh = new MailHelper();

Thread EMailThread = new Thread(new ParameterizedThreadStart(mh.SendMail));

EMailThread.Start(data.Key);

IsSendEMail.Add(data.Key); }

/// 把Gps数据放入对应的队列

public static void Enqueue(GpsData gpsData)

{ if (!IsClose)

{ gpsData.Id = ++gpsDataCount;

if (queueGpsDataCol.Keys.Contains(gpsData.Key))

{ getQueue(gpsData.Key).Enqueue(gpsData);}

else{ QueueGpsData queue = new QueueGpsData(gpsData.Key);

queue.Enqueue(gpsData);

addQueue(gpsData.Key, queue);

ServiceInfo.QueueCount = queueGpsDataCol.Count;}}}

5 结论

该Socket数据缓冲队列设计具有一定的实用性,通过优化设计,此方案应对大多数数据转发场景已经基本够用,达到了预期的效果。

参考文献

[1]李敏波编.C#高级编程[M].清华大学出版社.

[2]邱郁惠编.visual studio 2010和UML黄金法则[M].机械工业出版社.