Ace_Acceptor是ACE的接收器之一,此次使用涉及了这个类的三个函数:open\accept_svc_handler\activate_svc_handler。
其中open函数的原型之一:
/** * Open the contained @c PEER_ACCEPTOR object to begin listening, and * register with the specified reactor for accept events. An * acceptor can only listen to one port at a time, so make sure to * @c close() the acceptor before calling @c open() again. * * The @c PEER_ACCEPTOR handle is put into non-blocking mode as a * safeguard against the race condition that can otherwise occur * between the time when the passive-mode socket handle is "ready" * and when the actual @c accept() call is made. During this * interval, the client can shutdown the connection, in which case, * the @c accept() call can hang. * * @param local_addr The address to listen at. * @param reactor Pointer to the ACE_Reactor instance to register * this object with. The default is the singleton. * @param flags Flags to control what mode an accepted socket * will be put into after it is accepted. The only * legal value for this argument is @c ACE_NONBLOCK, * which enables non-blocking mode on the accepted * peer stream object in @c SVC_HANDLER. The default * is 0. * @param use_select Affects behavior when called back by the reactor * when a connection can be accepted. If non-zero, * this object will accept all pending connections, * instead of just the one that triggered the reactor * callback. Uses ACE_OS::select() internally to * detect any remaining acceptable connections. * The default is 1. * @param reuse_addr Passed to the @c PEER_ACCEPTOR::open() method with * @p local_addr. Generally used to request that the * OS allow reuse of the listen port. The default is 1. * * @retval 0 Success * @retval -1 Failure, @c errno contains an error code. */ virtual int open (const ACE_PEER_ACCEPTOR_ADDR &local_addr, ACE_Reactor *reactor = ACE_Reactor::instance (), int flags = 0, int use_select = 1, int reuse_addr = 1);
其中第一个参数,一般传入ACE_NET_Addr,在通过字符串(ip:port)构造对象后,需要检查对象是否含有效地址。即使传入无效的地址对象,open也不会报错。
第二个参数是反应器,不建议直接传入单体,这个可以传入ACE_Dev_Poll_Reactor\ACE_Select_Reactor构造出来的ACE_Reactor,在reactor激活之后,open之后才会真正的接入链接。
一旦链接接入,就会触发acceptor的handle_input调用的主要函数就是accept_svc_handler\activate_svc_handler。原生的accept_svc_handler函数中,无超时设置,在多进程接收链接,出现惊群现象时,会导致竞争不到链接的进程卡死在accept,一般情况下需要重写设置一个超时时间。原生的activate_svc_handler会直接在接收线程内触发svc的handle_input,一旦此函数有耗时操作,也会阻塞acceptor,一般会将acceptor抛入异线程再进行接收数据。