用的ACE Reactor的acceptor-connector模型,现在开了个acceptor想限制最大连接数,就重新实现了虚函数make_svc_handler,在这个函数里,我对最大连接数进行了判断,超过连接数就返回-1或0,直接报Segmentation fault(core dumped)错误,后来为了测试,干脆在进入函数make_svc_handler之后,什么也不执行,马上返回0或-1,还是不行,报同样的错误,有没有用过ACE的,请问我该怎么才能实现限制连接数目?
调试欢乐多
当最大连接数超过指定数后,返回-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来实现最大连接的,不知道具体怎么实现啊?
return 0;
试试,
先说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的连接需要忍受先暂时允许连接,然后马上断开的额外开销,一般情况可行,但是不停处理处理非法连接也会影响系统性能,也许加硬件上防火墙会更好,不过软件能做的也就这些了。