用的ACE Reactor的acceptor-connector模型,现在开了个acceptor想限制最大连接数,就重新实现了虚函数make_svc_handler,在这个函数里,我对最大连接数进行了判断,超过连接数就返回-1或0,直接报Segmentation fault(core dumped)错误,后来为了测试,干脆在进入函数make_svc_handler之后,什么也不执行,马上返回0或-1,还是不行,报同样的错误,有没有用过ACE的,请问我该怎么才能实现限制连接数目?

解决方案 »

  1.   

    又详细的测了下,具体问题如下:
    当最大连接数超过指定数后,返回-1,则会不停重复进入make_svc_handler函数
    如果返回0,则会报Segmentation fault(core dumped)错误,具体代码类似:#define MAX_NUMS 2
    int currentnum = 0;
    class  My_Acceptor :  public  ACE_Acceptor < Service, ACE_SOCK_ACCEPTOR >
    {
    public :
       int  make_svc_handler (Service  *& sh)
         {
            if(currentnum++>MAX_NUMS)
            {
                 ACE_DEBUG((LM_DEBUG,"up to max num\n"));
                 return -1;
                 //这里如果 return -1,则会不停进入当前函数
                 //return 0;
                 //这里如果 return 0,则程序会down掉,报Segmentation fault(core dumped)
            }
            if  (sh  ==   0 )
            ACE_NEW_RETURN (sh,
                            Service ( this -> processor_),
                             - 1 );       //  Set the reactor of the newly created <SVC_HANDLER> to the same
           //   reactor that this <ACE_Acceptor> is using.
            sh -> reactor ( this -> reactor ());
            return   0 ;
        }} 
    看到ACE开发指南上面说的,可以通过修改make_svc_handler来实现最大连接的,不知道具体怎么实现啊?
      

  2.   

    sh = 0;
    return 0;
    试试,
      

  3.   

    查看了ACE的源码,终于弄明白了。
    先说return 0 会down掉,因为ACE框架认为返回0就是正确创建了Service的对象,接下来会调用这个对象,而实际上,程序没有创建对象,因而调用会出错。
    再说return -1会不停进入当前函数,那是因为采用select模型,只要有消息没有处理,会一直不停的调用acceptor的handle_input函数,进而调用make_svc_handler函数。仔细想想,用make_svc_handler来限制最大连接数,按道理应该这样做,但是实际上并不一定,make_svc_handler只是创建服务对象的钩子函数,如果采用Epoll的ET模式,或许会是一个好方法,因为系统不会重复的通知你去处理,只会通知你一次。
    而实际上,当需要限制最大连接数的时候,往往想过滤掉某些IP,这个时候用make_svc_handler就无能为力了,因为这个时候还没有accept,还不知道对方的IP地址,比较好的方法是在server的open函数里,检验IP的合法性,进行过滤。这样可以避免前面提出的问题,但是对于非法IP的连接需要忍受先暂时允许连接,然后马上断开的额外开销,一般情况可行,但是不停处理处理非法连接也会影响系统性能,也许加硬件上防火墙会更好,不过软件能做的也就这些了。