ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

23
ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998

Transcript of ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

Page 1: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

ACE Tutorial

Laura A. Paterno

Software Workshop

20 January 1998

Page 2: 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

Page 3: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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.

Page 4: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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

Page 5: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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

Page 6: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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

Page 7: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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

Page 8: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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);

Page 9: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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)

Page 10: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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();}

Page 11: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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_;

};

Page 12: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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;

}

Page 13: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

January 19-23, 1998

Software Workshop 13

Output from Example

What you would see when run on NT

Page 14: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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;

Page 15: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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;

};

Page 16: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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_;

};

Page 17: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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 ();

}

Page 18: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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;

}

Page 19: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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;

}

Page 20: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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_;

};

Page 21: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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 ();

}

Page 22: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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;

}

}

Page 23: ACE Tutorial Laura A. Paterno Software Workshop 20 January 1998.

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;

}