1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
//=============================================================================
/**
* @file Network_Events.cpp
*
* $Id: Network_Events.cpp 93639 2011-03-24 13:32:13Z johnnyw $
*
*
* 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(20002)).
*
*
* @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"
#include "ace/OS_main.h"
class Network_Handler : public ACE_Event_Handler
{
public:
/// Default constructor
Network_Handler (ACE_SOCK_Stream &s);
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_UNUSED_ARG (result);
}
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)
{
ACE_DEBUG ((LM_DEBUG, "Network_Handler::handle_close handle = %d\n", handle));
this->stream_.close ();
delete this;
ACE_Reactor::end_event_loop ();
return 0;
}
class Network_Listener : public ACE_Event_Handler
{
public:
/// Default constructor
/// Default constructor
Network_Listener (void);
~Network_Listener (void);
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);
ACE_UNUSED_ARG (result);
}
Network_Listener::~Network_Listener (void)
{
}
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_UNUSED_ARG (result);
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)
{
ACE_DEBUG ((LM_DEBUG, "Network_Listener::handle_close handle = %d\n", handle));
this->acceptor_.close ();
delete this;
return 0;
}
int
ACE_TMAIN (int, ACE_TCHAR *[])
{
Network_Listener *listener = 0;
listener = new Network_Listener;
ACE_Reactor::run_event_loop ();
return 0;
};
|