summaryrefslogtreecommitdiff
path: root/examples/Reactor/WFMO_Reactor/test_network_events.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'examples/Reactor/WFMO_Reactor/test_network_events.cpp')
-rw-r--r--examples/Reactor/WFMO_Reactor/test_network_events.cpp203
1 files changed, 203 insertions, 0 deletions
diff --git a/examples/Reactor/WFMO_Reactor/test_network_events.cpp b/examples/Reactor/WFMO_Reactor/test_network_events.cpp
new file mode 100644
index 00000000000..3f3c7fdcd20
--- /dev/null
+++ b/examples/Reactor/WFMO_Reactor/test_network_events.cpp
@@ -0,0 +1,203 @@
+// $Id$
+//
+// ============================================================================
+//
+// = LIBRARY
+// examples
+//
+// = FILENAME
+// test_network_events.cpp
+//
+// = DESCRIPTION
+//
+// This application tests Reactor to make sure that it responds
+// correctly to different kinds of network events.
+//
+// The test starts off by creating a Network_Listener, that listens
+// for connections at ACE_DEFAULT_SERVER_PORT. When a client
+// connects, a Network_Handler is created. Network_Handler reads
+// messages off the socket and prints them out. This is done until
+// the remote side shuts down. Multiple clients can connect at the
+// same time.
+//
+// Events tested in this example includes ACCEPT, READ, and CLOSE masks.
+//
+// To run this example, start an instance of this example and
+// connect to it using telnet (to port
+// ACE_DEFAULT_SERVER_PORT(10002)).
+//
+// = AUTHOR
+// Irfan Pyarali
+//
+// ============================================================================
+
+#include "ace/Reactor.h"
+#include "ace/WFMO_Reactor.h"
+#include "ace/INET_Addr.h"
+#include "ace/SOCK_Stream.h"
+#include "ace/SOCK_Acceptor.h"
+
+ACE_RCSID(WFMO_Reactor, test_network_events, "$Id$")
+
+class Network_Handler : public ACE_Event_Handler
+{
+public:
+ Network_Handler (ACE_SOCK_Stream &s);
+ // Default constructor
+
+ virtual int handle_input (ACE_HANDLE handle);
+ virtual int handle_close (ACE_HANDLE handle,
+ ACE_Reactor_Mask close_mask);
+ virtual ACE_HANDLE get_handle (void) const;
+
+ ACE_SOCK_Stream stream_;
+
+};
+
+Network_Handler::Network_Handler (ACE_SOCK_Stream &s)
+ : stream_ (s)
+{
+ this->reactor (ACE_Reactor::instance ());
+
+ int result = this->reactor ()->register_handler (this, READ_MASK);
+ ACE_ASSERT (result == 0);
+}
+
+ACE_HANDLE
+Network_Handler::get_handle (void) const
+{
+ return this->stream_.get_handle ();
+}
+
+int
+Network_Handler::handle_input (ACE_HANDLE handle)
+{
+ ACE_DEBUG ((LM_DEBUG, "Network_Handler::handle_input handle = %d\n", handle));
+
+ while (1)
+ {
+ char message[BUFSIZ];
+ int result = this->stream_.recv (message, sizeof message);
+ if (result > 0)
+ {
+ message[result] = 0;
+ ACE_DEBUG ((LM_DEBUG, "Remote message: %s\n", message));
+ }
+ else if (result == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG, "Connection closed\n"));
+ return -1;
+ }
+ else if (errno == EWOULDBLOCK)
+ {
+ return 0;
+ }
+ else
+ {
+ ACE_DEBUG ((LM_DEBUG, "Problems in receiving data, result = %d", result));
+ return -1;
+ }
+ }
+}
+
+int
+Network_Handler::handle_close (ACE_HANDLE handle,
+ ACE_Reactor_Mask close_mask)
+{
+ ACE_DEBUG ((LM_DEBUG, "Network_Handler::handle_close handle = %d\n", handle));
+
+ this->stream_.close ();
+ delete this;
+ return 0;
+}
+
+class Network_Listener : public ACE_Event_Handler
+{
+public:
+ Network_Listener (void);
+ // Default constructor
+ ~Network_Listener (void);
+ // Default constructor
+
+ virtual int handle_input (ACE_HANDLE handle);
+ virtual int handle_close (ACE_HANDLE handle,
+ ACE_Reactor_Mask close_mask);
+ ACE_HANDLE get_handle (void) const;
+
+ ACE_INET_Addr local_address_;
+ ACE_SOCK_Acceptor acceptor_;
+};
+
+Network_Listener::Network_Listener (void)
+ : local_address_ (ACE_DEFAULT_SERVER_PORT),
+ acceptor_ (local_address_, 1)
+{
+ this->reactor (ACE_Reactor::instance ());
+ int result = this->reactor ()->register_handler (this,
+ ACE_Event_Handler::ACCEPT_MASK);
+ ACE_ASSERT (result == 0);
+}
+
+Network_Listener::~Network_Listener (void)
+{
+ this->reactor ()->remove_handler (this, ACE_Event_Handler::ACCEPT_MASK ||
+ ACE_Event_Handler::DONT_CALL);
+ this->handle_close (this->get_handle (), ACE_Event_Handler::ALL_EVENTS_MASK);
+}
+
+ACE_HANDLE
+Network_Listener::get_handle (void) const
+{
+ return this->acceptor_.get_handle ();
+}
+
+int
+Network_Listener::handle_input (ACE_HANDLE handle)
+{
+ ACE_DEBUG ((LM_DEBUG, "Network_Listener::handle_input handle = %d\n", handle));
+
+ ACE_INET_Addr remote_address;
+ ACE_SOCK_Stream stream;
+
+ // Try to find out if the implementation of the reactor that we are
+ // using requires us to reset the event association for the newly
+ // created handle. This is because the newly created handle will
+ // inherit the properties of the listen handle, including its event
+ // associations.
+ int reset_new_handle = this->reactor ()->uses_event_associations ();
+
+ int result = this->acceptor_.accept (stream, // stream
+ &remote_address, // remote address
+ 0, // timeout
+ 1, // restart
+ reset_new_handle); // reset new handler
+ ACE_ASSERT (result == 0);
+
+ ACE_DEBUG ((LM_DEBUG, "Remote connection from: "));
+ remote_address.dump ();
+
+ Network_Handler *handler;
+ ACE_NEW_RETURN (handler, Network_Handler (stream), -1);
+
+ return 0;
+}
+
+int
+Network_Listener::handle_close (ACE_HANDLE handle,
+ ACE_Reactor_Mask close_mask)
+{
+ ACE_DEBUG ((LM_DEBUG, "Network_Listener::handle_close handle = %d\n", handle));
+
+ this->acceptor_.close ();
+ return 0;
+}
+
+int
+main (int, char *[])
+{
+ Network_Listener listener;
+
+ ACE_Reactor::run_event_loop ();
+
+ return 0;
+};