📄 connection_handler.cpp
字号:
// Connection_Handler.cpp,v 4.21 2003/11/05 02:04:53 dhinton Exp
// ============================================================================
//
// = FILENAME
// Connection_Handler.cpp
//
// = DESCRIPTION
// This test illustrates how to use the Acceptor pattern to
// create multiple threads, each running its own Reactor. You
// can connect to this via telnet and keep typing until you enter
// '^D'.
//
// = AUTHOR
// Doug Schmidt
//
// ============================================================================
#include "ace/Acceptor.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/Service_Config.h"
#include "ace/Thread.h"
#include "ace/Signal.h"
#include "Connection_Handler.h"
ACE_RCSID(misc, Connection_Handler, "Connection_Handler.cpp,v 4.21 2003/11/05 02:04:53 dhinton Exp")
int
Connection_Handler::open (void *)
{
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) in open()\n"));
// Make ourselves an Active Object.
return this->activate (THR_NEW_LWP | THR_DETACHED);
}
int
Connection_Handler::close (u_long)
{
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) in close()\n"));
// Shut ourself down. Note that this doesn't destroy the thread,
// just the state of the object.
this->destroy ();
return 0;
}
int
Connection_Handler::svc (void)
{
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) in svc()\n"));
this->finished_ = 0;
// Create our own personal Reactor just for this thread. Note that
// we create this on the stack of the thread since it's only used
// for the duration of this connection!
ACE_Reactor reactor;
// Each <ACE_Svc_Handler> has its own <ACE_Reactor *>. By default,
// this points to the <Acceptor's> Reactor. However, we can point
// it to our local Reactor, which is what we do in this case.
this->reactor (&reactor);
// Register ourselves to handle input in this thread without
// blocking.
if (this->reactor ()->register_handler
(this, ACE_Event_Handler::READ_MASK) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
"can' (%P|%t) t register with reactor\n"),
-1);
// Schedule a timer.
else if (this->reactor ()->schedule_timer (this,
(const void *) this,
ACE_Time_Value (2),
ACE_Time_Value (2)) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
"(%P|%t) can't register with reactor\n"),
-1);
else
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) connected with client\n"));
// Keep looping until we receive SIGQUIT or the client shutsdown.
while (this->finished_ == 0)
{
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) handling events\n"));
this->reactor ()->handle_events ();
}
// Cancel all pending timeouts.
this->reactor ()->cancel_timer (this);
// Remove ourselves from the Reactor.
this->reactor ()->remove_handler
(this, ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL);
// Zero-out the Reactor field so it isn't accessed later on.
this->reactor (0);
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) exiting svc\n"));
return 0;
}
int
Connection_Handler::handle_close (ACE_HANDLE,
ACE_Reactor_Mask)
{
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) in handle_close \n"));
// Signal the svc() event loop to shut down.
this->finished_ = 1;
return 0;
}
int
Connection_Handler::handle_input (ACE_HANDLE)
{
char buf[BUFSIZ];
ACE_DEBUG ((LM_DEBUG, "(%P|%t) handle_input\n"));
switch (this->peer ().recv (buf, sizeof buf))
{
case -1:
ACE_ERROR_RETURN ((LM_ERROR,
"(%P|%t) %p bad read\n",
"client logger"),
-1);
case 0:
ACE_ERROR_RETURN ((LM_ERROR,
"(%P|%t) closing log daemon (fd = %d)\n",
this->get_handle ()),
-1);
default:
if (buf[0] == (char) EOF)
ACE_ERROR_RETURN ((LM_ERROR,
"(%P|%t) closing log daemon (fd = %d)\n",
this->get_handle ()),
-1);
else
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) from client: %s",
buf));
}
return 0;
}
int
Connection_Handler::handle_signal (int signum,
siginfo_t *,
ucontext_t *)
{
// @@ Note that this code is not portable to all OS platforms since
// it uses print statements within signal handler context.
ACE_DEBUG ((LM_DEBUG,
"received signal %S\n",
signum));
this->finished_ = 1;
return 0;
}
int
Connection_Handler::handle_timeout (const ACE_Time_Value &tv,
const void *arg)
{
ACE_UNUSED_ARG (tv);
#if defined (ACE_NDEBUG)
ACE_UNUSED_ARG (arg);
#endif /* ACE_NDEBUG */
ACE_ASSERT (arg == this);
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) handling timeout from this = %u\n",
this));
return 0;
}
// Define an Acceptor for the <Connection_Handler>.
typedef ACE_Acceptor <Connection_Handler, ACE_SOCK_ACCEPTOR>
Connection_Acceptor;
int
main (int argc, char *argv[])
{
ACE_Service_Config daemon (argv[0]);
u_short port = argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_DEFAULT_SERVER_PORT;
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) in main\n"));
// Acceptor factory.
Connection_Acceptor peer_acceptor;
// Create an adapter to end the event loop.
ACE_Sig_Adapter sa ((ACE_Sig_Handler_Ex) ACE_Reactor::end_event_loop);
// Register the signal handler adapter.
if (ACE_Reactor::instance ()->register_handler (SIGINT, &sa) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
"%p\n",
"register_handler"),
-1);
// Open the Acceptor.
else if (peer_acceptor.open (ACE_INET_Addr (port),
ACE_Reactor::instance ()) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
"%p\n",
"open"),
-1);
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) starting up connection server\n"));
// Perform connection service until we receive SIGINT.
while (ACE_Reactor::event_loop_done() == 0)
ACE_Reactor::run_event_loop ();
ACE_DEBUG ((LM_DEBUG,
"(%P|%t) shutting down connection server\n"));
return 0;
}
#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
template class ACE_Acceptor<Connection_Handler, ACE_SOCK_ACCEPTOR>;
template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
#pragma instantiate ACE_Acceptor<Connection_Handler, ACE_SOCK_ACCEPTOR>
#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -