注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

转载:如何创建和使用socket链接池  

2010-09-23 12:06:22|  分类: 网络服务编程技术 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

 

如何创建和使用socket链接池

作者:吴康彬

    采用CS方式的程序不可避免都要碰到socket连接的问题,很多时候,使用编程语言当中自带的socket库,使用起来多少有些不习惯,虽然系统自带的库在很多异常处理,稳定性上下了很多功夫,但是要去理解和使用那些库,比如做socket连接池不免要走很多弯路。在这里我和大家讨论下怎么样创建和使用socket链接池。

    一般socket链接有以下两种方式:长(常)链接和短链接。

    长链接:当数据发送完成后socket链接不断开。一直保留到异常或者是程序退出为止,这种方式的好处是不用每次去发起连接断开,在速度上可以比短连接要快一些,但是相对来说对服务器的资源压力也要大些。长链接用的范围很广,比如游戏系统,qq等等,长(常)链接一般还需要定时向服务器ping数据,以保证socket链接畅通。当ping不通服务器时,需要重新开启链接。

    短链接:当一次数据发送完毕后,主动断开链接,每次发送数据都要一次链接、断开操作,这种方式的好处是:对服务器的资源占用相对来说比较小,但是由于每次都要重新链接,速度开销上也比较大,这种方式对于那种不需要经常与服务器交互的情况下比较适用。

    上面两种方法在用户量非常大的情况下都存在着很大的不足,因此,我们考虑可以用一种折衷的办法,那就是使用socket的连接池。

    程序一开始初始化创建若干数量的长链接。给他们设置一个标识位,这个标识位表示该链接是否空闲的状态。当需要发送数据的时候,系统给它分配一个当前空闲的链接。同时,将得到的链接设置为“忙”,当数据发送完毕后,把链接标识位设置为“闲”,让系统可以分配给下个用户,这样使得两种方式的优点都充分的发挥出来了。杭州携购网络科技有限公司旗下的携购独立购物网(http://www.shopxg.com)系统采用的就是这种方式。用户数量足够多的时候,只需要动态增加链接池的数量即可。

    下面我们用具体的程序来讲解下:

    首先我们声明一个socket类:

       public class XieGouSocket

       {

              public Socket m_socket;  //Socket对象

              public bool m_isFree;  //判断是否空闲

              public int m_index;  //在链接缓存池中的索引值

       }

      

    下面的函数是创建socket链接池,这里为了使代码更加清晰,我特地把异常处理部分全部取掉了。

       public XieGouSocket[] m_socket; //先定义个缓冲池

       public void  CreateSocketPool()

       {

              string ip= “127.0.0.1”;

              string port= 2003;

              IPAddress serverIp=IPAddress.Parse(ip);

              int serverPort=Convert.ToInt32(port);

              IPEndPoint iep=new IPEndPoint(serverIp,serverPort);

              m_socket = new XieGouSocket[200];

              for(int i =0; i < 200 ; i ++)

              {

                    m_socket[i] = new XieGouSocket();

                    m_socket[i].m_index = i ;

                    m_socket[i].m_isFree = true;

                    m_socket[i].m_socket =new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

                     m_socket[i].m_socket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.SendTimeout,1000); 

                    m_socket[i].m_socket.Connect(iep);

              }

       }

    下面的函数是获取当前空闲的socket链接:

    因为是多线程,所以我们需要加一个原子操作,定义一个原子变量,以防止多个线程之间抢占资源问题的发生。

       private   static   Mutex   m_mutex=new   Mutex();

       public static  XieGouSocket GetFreeConnection()

       {     

              m_mutex.WaitOne(); //先阻塞

              for(int i =0; i < m_socket.Length ; i ++)

              {

                    if(m_socket[i].m_isFree) //如果找到一个空闲的

                    {

                           m_socket[i].m_isFree = false;

                           m_mutex.ReleaseMutex();//释放资源                                                        

                           return m_socket[i];

                    }

              }

              //如果没有空闲的链接,要么等待,要么程序再动态创建一个链接。

              m_mutex.ReleaseMutex();//释放资源

                                 

              return null;

       }

    当数据发送完毕后,程序必须将m_isFree 设置为 False。否则只使用不释放,程序很快就溢出了。

    基本的思路就是这样的,大家可以在此基础上好好的改进下,这样运行的效率就比较高了。

        欢迎大家与我交流。QQ:8814730 Email:wkb@xiegoo.com

  评论这张
 
阅读(913)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017