Date post: | 04-Jan-2016 |
Category: |
Documents |
Upload: | patricia-kennedy |
View: | 221 times |
Download: | 0 times |
ACE Tutorial
Laura A. Paterno
Software Workshop
20 January 1998
January 19-23, 1998
Software Workshop 2
What is ACE?
ACE - Adaptive Communications Environment
“ACE is a freely available OO toolkit containing a rich set of reusable wrappers, class categories, and frameworks that perform common network programming tasks across a wide range of OS platforms.”
object-oriented written in C++ and has JAVA version uses many Patterns from Gamma, et al.
cross platform compatible use the same tar file to install on UNIX and NT shields users from platform dependent OS features
threads and synchronization interprocess communicationevent demultiplexing
handling Asynchronous I/O, timers, & signals
dynamic linkingmemory-mapped files and shared memory
January 19-23, 1998
Software Workshop 3
Ace Architecture
layered architecture lower layers are wrappers which encapsulate existing
OS network programming mechanisms upper layers provide OO frameworks and
components which cover a broader range of application-oriented network tasks and services.
January 19-23, 1998
Software Workshop 4
Services Provided by Ace
Event demultiplexing and event handler dispatching async I/O, timers, signals, etc.
Connection establishment and service initialization Interprocess communication and shared memory
management dynamic configuration of distributed
communication services at installation and/or run-time
Concurrency/parallelism and synchronization threads, mutexes and semaphores, conditions, etc.
Components for higher-level distributed services common network services
January 19-23, 1998
Software Workshop 5
ACE’s Lowest Layer
Operating System(OS) layer is the lowest layer in the system it encapsulates all the Operating System specific
details for: threads and synchronization (concurrency)
mutexes, semaphores, conditions, etc.
interprocess communication (IPC) sockets, pipes, streams, etc.
event demultiplexing select, poll, timers, signals, etc.
explicit dynamic linking share .so vs .dll
memory-mapped files and shared memory
January 19-23, 1998
Software Workshop 6
ACE OO Wrappers
One layer above the OS layer Encapsulate and enhance concurrency, IPC, event
demultiplexing and virtual memory mechanisms Provide type-secure interfaces Include:
IPC_SAP - interprocess communication package that hides the mechanism by which you are communicating
sockets, pipes, streams, etc.
Service Initialization - provide components that decouple active and passive roles from tasks a service provides once initialization is complete.
Concurrency Mechanisms - expand concurrency mechanisms to higher levels (Thread managers, active objects)
Memory management - dynamic allocation/deallocation of shared memory and local memory
CORBA Intergration
January 19-23, 1998
Software Workshop 7
IPC_SAP
Hierarchy of classes that encapsulate the standard I/O handle-based OS local and remote IPC mechanism that offer connection-oriented and connectionless protocols TCP/IP, UDP, named pipes, etc.
Help simplify network programming shield applications from error-prone details
support diverse network address formats but hide from user via type-secure interface
combine several operations to form a single operation
combine socket, bind and listen which are required to enable a server for receiving connection requests
parameterize IPC mechanisms into applicationshelps improve portability
enhance code sharing between the common code shared by the different IPC mechanisms
January 19-23, 1998
Software Workshop 8
Example of how code gets simplified
C version of making a server able to receive connection requestsint s = socket(PF_INET, SOCK_STREAM, 0);sockaddr_in addr;memset(&addr, 0, sizeof addr);addr.sin_family = AF_INETaddr.sin_port = htons(port);addr.sin_addr.s_addr = INADDR_ANY;bind(s, &addr, addr_len);listen(s);
ACE versionACE_SOCK_Acceptor acceptor((ACE_INET_Addr) port);
January 19-23, 1998
Software Workshop 9
ACE Frameworks
One layer above the Wrappers Support dynamic configuration of network
deamons composed of application services Include
Reactor - provides extensible demultiplexer that dispatches handlers in response to various types of events
I/O based, timer-based, signal-based, & synchronization-based
Service Configurator - supports construction of applications whose services may be configured dynamically at installation and/or run-time
Streams - simplify development of concurrent communication applications composed of 1 or more hierarchically-related services (such as protocol stacks)
January 19-23, 1998
Software Workshop 10
Reactor-Based Server Logging Daemon
class Logging_Acceptor : public ACE_Event_Handler{public: // Override functions in ACE_Event_Handler virtual ACE_HANDLE get_handle() const {return this->_acceptor->get_handle(); } virtual int handle_input(ACE_HANDLE h);private: ACE_SOCK_acceptor _acceptor;}const int LOGGER_PORT = 10000;
intmain(){ ACE_Reactor reactor; Logging_Acceptor a((ACE_INET_Addr) LOGGER_PORT);reactor.register_handler(&a);for(;;) // loop forever reactor.handle_events();}
January 19-23, 1998
Software Workshop 11
Reactor Example Using Timeouts
// FILENAME - test_timeouts.cpp
// DESCRIPTION - This example shows how to
// write Reactors that handle events for some
// fixed time. When run the output is:
// foo, bar, foo, bar, foo, foo, bar, foo,
// bar, foo
#include "ace/Reactor.h”
class Timeout_H : public ACE_Event_Handler
{
public:
Timeout_H () : count_ (0) {}
virtual int handle_timeout(
const ACE_Time_Value &tv, const void *arg)
{ // Print out when timeouts occur.
ACE_DEBUG((LM_DEBUG, "%d timeout occurred
for %s.\n", ++count_, (char *) arg));
return 0;
}
private:
int count_;
};
January 19-23, 1998
Software Workshop 12
Reactor Example Using Timeouts
int main (int, char *[])
{
Timeout_H handler;
// Register a 3 second timer.
ACE_Time_Value bar_tv (3);
ACE_Reactor::instance()->schedule_timer(
&handler, (void *) "Bar", bar_tv, bar_tv);
// Register a 2 second timer.
ACE_Time_Value foo_tv (2);
ACE_Reactor::instance()->schedule_timer(
&handler, (void *) "Foo", foo_tv, foo_tv);
// Handle events for 12 seconds.
ACE_Time_Value rt (12);
if (ACE_Reactor::run_event_loop(rt) == -1)
ACE_ERROR_RETURN((LM_ERROR, "%p.\n",
"main"), -1);
return 0;
}
January 19-23, 1998
Software Workshop 13
Output from Example
What you would see when run on NT
January 19-23, 1998
Software Workshop 14
Reactor Network Events Test
// FILENAME - test_network_events.cpp
// DESCRIPTION - This application tests
// Reactor to make sure that it responds
// correctly to different kinds of network
// events. 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)).
#include "ace/Reactor.h"
#include "ace/WFMO_Reactor.h"
#include "ace/INET_Addr.h"
#include "ace/SOCK_Stream.h"
#include "ace/SOCK_Acceptor.h"
// Globals for this test
int stop_test = 0;
ACE_Reactor reactor;
January 19-23, 1998
Software Workshop 15
Main Program
int
main (int, char *[])
{
Network_Listener listener;
int result = 0;
while (!stop_test && result != -1)
result = reactor.handle_events ();
return 0;
};
January 19-23, 1998
Software Workshop 16
Network_Listener Class
class Network_Listener : public ACE_Event_Handler
{
public:
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_;
};
January 19-23, 1998
Software Workshop 17
Network_Listener Methods
Network_Listener::Network_Listener (void)
: local_address_ (ACE_DEFAULT_SERVER_PORT),
acceptor_ (local_address_, 1)
{
this->reactor (&::reactor);
ACE_ASSERT(this->reactor()->
register_handler(this,
ACE_Event_Handler::ACCEPT_MASK) == 0);
}
ACE_HANDLE
Network_Listener::get_handle(void) const
{
return this->acceptor_.get_handle ();
}
January 19-23, 1998
Software Workshop 18
Network_Listener Methods
handle_input Methodint 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;
// Check if implementation of reactor that we are
// using requires reset of event association for
// the newly created handle. This is because the
// newly created handle inherits properties of the
// listen handle, including its event associations.
int reset_new_handle =
this->reactor()->uses_event_associations();
ACE_ASSERT (this->acceptor_.accept(stream, &remote_address, 0, 1, reset_new_handle) == 0);
ACE_DEBUG ((LM_DEBUG, "Remote connection from: "));
remote_address.dump ();
Network_Handler *handler = new Network_Handler (stream);
return 0;
}
January 19-23, 1998
Software Workshop 19
Network_Listener Methods
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;
}
January 19-23, 1998
Software Workshop 20
Network_Handler class
class Network_Handler : public ACE_Event_Handler
{
public:
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_;
};
January 19-23, 1998
Software Workshop 21
Network_Handler Methods
Constructor
Network_Handler::Network_Handler (ACE_SOCK_Stream &s)
: stream_ (s)
{
this->reactor (&::reactor);
ACE_ASSERT (this->reactor ()->register_handler(this, READ_MASK) == 0);
}
get_handle MethodACE_HANDLE
Network_Handler::get_handle (void) const
{
return this->stream_.get_handle ();
}
January 19-23, 1998
Software Workshop 22
Network_Handler Methods
handle_input Methodint Network_Handler::handle_input(ACE_HANDLE handle)
{
ACE_DEBUG ((LM_DEBUG,"Network_Handler::handle_input
handle = %d\n", handle));
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));
return 0;
}
else if (result == 0) {
ACE_DEBUG ((LM_DEBUG, "Connection closed\n"));
return -1;
}
else {
ACE_DEBUG ((LM_DEBUG, "Problems in receiving
data, result = %d", result));
return -1;
}
}
January 19-23, 1998
Software Workshop 23
Network_Handler Methods
handle_close Method
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;
}