CS 342: Object-Oriented Software Development Lab
An Introduction to ACE
David L. LevineChristopher D. Gill
Department of Computer ScienceWashington University, St. Louis
flevine,[email protected]
http://classes.cec.wustl.edu/�cs342/
CS 342: OO Software Development Lab OO Patterns
Introduction to ACE
� What is ACE?
– OO middleware framework that implements many core designpatterns for concurrent communication software
– Targeted for developers of high-performance and real-timecommunication services and applications
– Simplifies and speeds development via reuse
� Why Use Frameworks? Why Use ACE? Why Use CommunicationMiddleware?
� How do we use ACE?
� The ADAPTIVE Communication Environment (ACE)
� Sources for more information
Copyright c 1997-2000 Dept. of Computer Science, Washington University 1
CS 342: OO Software Development Lab OO Patterns
Why Use Frameworks?
APPLICATIONAPPLICATION
SPECIFICSPECIFIC
LOGICLOGIC
USERUSER
INTERFACEINTERFACE
(A) CLASS LIBRARY ARCHITECTURE
NETWORKING
MATH ADTS
DATA
BASE
MATH
(B) FRAMEWORK ARCHITECTURE
ADTS
INVOKES
INVOKES
EVENT
LOOP
APPLICATION
SPECIFIC
LOGIC
CALL
BACKS
NETWORKING USER
INTERFACE
DATABASE
EVENT
LOOP
� Proven solutions
– Components
� Self-contained,ready-to-use ADTs
– Frameworks
� Reusable, semi-completeapplications
– Patterns
� Problem/solution pairs in acontext
– Architecture
� Families of relatedpatterns and components
Copyright c 1997-2000 Dept. of Computer Science, Washington University 2
CS 342: OO Software Development Lab OO Patterns
Why Use ACE?� Good example of a framework
� Provides many implementations of patterns
� Open-source
� It’s taking over the world ;-)
Copyright c 1997-2000 Dept. of Computer Science, Washington University 3
CS 342: OO Software Development Lab OO Patterns
Why Use Communication Middleware?
� System call-level programming is wrong abstraction forapplication developers
– Too low-level ! error codes, endless reinvention– Error-prone ! HANDLEs lack type-safety, thread cancellation
woes– Mechanisms do not scale ! Win32 TLS– Steep learning curve ! Win32 Named Pipes– Non-portable ! socket bugs– Inefficient ! i.e., tedious for humans
� GUI frameworks are inadequate for communication software
– Inefficient ! excessive use of virtual methods– Lack of features ! minimal threading and synchronization
mechanisms, no network services
Copyright c 1997-2000 Dept. of Computer Science, Washington University 4
CS 342: OO Software Development Lab OO Patterns
How Do We Use ACE?
� The Makefile takes care of most details, with two exceptions:– You must use GNU gmake instead of Sun make with this Makefile.– In order to run your ACE application, you must set your
LD_LIBRARY_PATHenvironment variable to find the ACE library– For Sun CC:% pkgadd sc% setenv LD_LIBRARY_PATH \
˜/ACE_wrappers/build/SunOS5_sunc++:$LD_LIBRARY_PATH% make
– For egcs:% pkgadd egcs% setenv LD_LIBRARY_PATH \
˜/ACE_wrappers/build/SunOS5_egcs:$LD_LIBRARY_PATH% make egcs=1
Copyright c 1997-2000 Dept. of Computer Science, Washington University 5
CS 342: OO Software Development Lab OO Patterns
The ADAPTIVE Communication Environment (ACE)
PROCESSES//THREADSTHREADS
DYNAMICDYNAMIC
LINKINGLINKING
MEMORYMEMORY
MAPPINGMAPPING
SELECTSELECT//IO COMPIO COMP
SYSTEMSYSTEM
VV IPCIPCSTREAMSTREAM
PIPESPIPES
NAMEDNAMED
PIPESPIPES
CAPISS
SOCKETSSOCKETS//TLITLI
COMMUNICATIONCOMMUNICATION
SUBSYSTEMSUBSYSTEM
VIRTUAL MEMORYVIRTUAL MEMORY
SUBSYSTEMSUBSYSTEM
GENERAL POSIX AND WIN32 SERVICES
PROCESSPROCESS//THREADTHREAD
SUBSYSTEMSUBSYSTEM
FRAMEWORKS ACCEPTORACCEPTOR CONNECTORCONNECTOR
SELF-CONTAINED
DISTRIBUTED
SERVICE
COMPONENTS
NAMENAME
SERVERSERVER
TOKENTOKEN
SERVERSERVER
LOGGINGLOGGING
SERVERSERVER
GATEWAYGATEWAY
SERVERSERVER
SOCKSOCK__SAPSAP//TLITLI__SAPSAP
FIFOFIFO
SAPSAP
LOGLOG
MSGMSG
SERVICESERVICE
HANDLERHANDLER
TIMETIME
SERVERSERVER
C++WRAPPER
FACADES
SPIPESPIPE
SAPSAP
CORBACORBA
HANDLERHANDLER
SYSVSYSVWRAPPERSWRAPPERS
SHAREDSHARED
MALLOCMALLOC
THE ACE ORBTHE ACE ORB
((TAOTAO))
JAWS ADAPTIVEJAWS ADAPTIVE
WEB SERVERWEB SERVER
MIDDLEWARE
APPLICATIONS
REACTORREACTOR//PROACTORPROACTOR
PROCESSPROCESS//THREADTHREAD
MANAGERSMANAGERS
STREAMSSTREAMS
SERVICESERVICE
CONFIGCONFIG--URATORURATOR
SYNCHSYNCH
WRAPPERSWRAPPERS
MEMMEM
MAPMAP
OS ADAPTATION LAYER
http://www.cs.wustl.edu/�schmidt/ACE.html
� ACE Overview
– A concurrent OOnetworkingframework
– Available in C++and Java
– Ported toVxWorks, POSIX,and Win32
� Related work
– x-Kernel– SysV STREAMS
Copyright c 1997-2000 Dept. of Computer Science, Washington University 6
CS 342: OO Software Development Lab OO Patterns
ACE Components� Interprocess communication
– sockets, pipes, signal, message passing, shared memory
� Event demultiplexing
– reactors, proactors
� Concurrency support
– executions (threads) and synchronization
� Service configuration
– dynamic linking
� Many other useful services
– output (logging), sophisticated container classes, high-resolutiontiming and timers, singleton management
Copyright c 1997-2000 Dept. of Computer Science, Washington University 7
CS 342: OO Software Development Lab OO Patterns
ACE Statistics
� ACE contains > 175,000 lines ofC++
– Over 20 person-years of effort
� Ported to UNIX, Win32, MVS, andembedded platforms
– e.g., VxWorks, LynxOS, Chorus
� Large user community
– www.cs.wustl.edu/�schmidt/ACE-users.html
� Currently used bydozens of companies
– Bellcore, Boeing,Ericsson, Kodak,Lockheed, Lucent,Motorola, SAIC,Siemens, StorTek,etc.
� Supported commercially
– www.riverace.com– www.ociweb.com
Copyright c 1997-2000 Dept. of Computer Science, Washington University 8
CS 342: OO Software Development Lab OO Patterns
Patterns for Communication Middleware
EventPatterns
ConcurrencyPatterns
ExternalPolymorphism
WrapperFacade
Connector
Acceptor
ThreadPool
Thread-perSession
Thread-perRequest
AsynchronousCompletion
Token
ThreadSpecificStorage
ActiveObject
Half-Sync/Half-Async
Leader/Followers
ServiceConfigurator
Object LifetimeManager
Reactor
Proactor
DoubleCheckedLocking
Thread-Safe
Interface
ScopedLocking
StrategizedLocking
InitializationPatterns
SynchronizationPatterns
� Observation
– Failures rarely resultfrom unknown scientificprinciples, but fromfailing to apply provenengineering practicesand patterns
� Benefits of Patterns
– Facilitate design reuse– Preserve crucial design
information– Guide design choices
Copyright c 1997-2000 Dept. of Computer Science, Washington University 9
CS 342: OO Software Development Lab OO Patterns
Active Objects with ACE Tasks
ACTIVEACTIVE
:: MessageMessageQueueQueue
tt22 : :
TaskTask2: enqueue (msg)2: enqueue (msg)
1: put (msg)1: put (msg)
:: MessageMessageQueueQueue
tt11 : :
TaskTask
:: MessageMessageQueueQueue
tt33 : :
TaskTask
6: put (msg)6: put (msg)
3: svc ()3: svc ()4: dequeue (msg)4: dequeue (msg)5: do_work(msg)5: do_work(msg)
ACTIVEACTIVE
ACTIVEACTIVE
:: TASK TASK
STATESTATE
:: TASK TASK
STATESTATE
:: TASK TASK
STATESTATE
� ACE Task Features
– Queueing– Event demultiplexing– Concurrency– Dynamic linking
Copyright c 1997-2000 Dept. of Computer Science, Washington University 10
CS 342: OO Software Development Lab OO Patterns
The ACE Stream Class Category
NETWORK INTERFACE
OR PSEUDO-DEVICES
STREAMTail
Multiplexor
APPLICATION
Stream
STREAMHead
APPLICATION
Stream
UP
ST
RE
AMD
OW
NS
TR
EA
M
MESSAGEMESSAGE WRITEWRITE
TASKTASK
READREAD
TASKTASKMODULEMODULE
open()=0close()=0put()=0svc()=0
� ACE Stream Features
– Layered servicecomposition
– Synchronous andasynchronousmessaging
– Dynamic configuration
Copyright c 1997-2000 Dept. of Computer Science, Washington University 11
CS 342: OO Software Development Lab OO Patterns
Network Programming Alternatives
USER
SPACE
KERNEL
SPACE
DOC MIDDLEWAREDOC MIDDLEWARE
SOCKETS AND SOCKETS AND TLITLITLI
OPENOPEN///CLOSECLOSE///PUTMSGPUTMSG///GETMSGGETMSG
STREAMSSTREAMSSTREAMSFRAMEWORKFRAMEWORK
LE
VE
L O
F
AB
ST
RA
CT
ION
TPITPINPINPIDLPIDLPI
HI
LO
� Communicationsoftware can beprogrammed atseveral levels ofabstraction
� Different levelsare appropriatefor differenttasks
Copyright c 1997-2000 Dept. of Computer Science, Washington University 12
CS 342: OO Software Development Lab OO Patterns
Standard APIs for Network IPC
USER
SPACE
DISTRIBUTED
APPLICATION 1
DISTRIBUTED
APPLICATION 3
DISTRIBUTED
APPLICATION 2
KERNEL
SPACE
SYSTEM V
TLI API
SYSTEM V
TLI APIBSD SOCKET
API
SOCKET
API
APPLICATION
PROCESS 3592
APPLICATION
PROCESS 4183
APPLICATION
PROCESS 8729
OSOS KERNEL KERNEL
PROTOCOL SERVICESPROTOCOL SERVICES
((TCPTCP//IPIP,, OSI,OSI, ETC ETC.).)
NETWORK
INTERFACE
� Sockets and TLIallow access tolower-level IPCmechanisms, e.g.:
– TCP/IP– XNS and Novell
IPX NetWareprotocols
– UNIX domainsockets
– OSI protocols
Copyright c 1997-2000 Dept. of Computer Science, Washington University 13
CS 342: OO Software Development Lab OO Patterns
Socket Taxonomy
CONNECTION
CONNECTION//
COMM
UNICATIO
N
COMM
UNICATIO
N
ROLEROLE
LOCALLOCAL LOCALLOCAL//REMOTEREMOTE
ST
RE
AM
ST
RE
AM
ACTIVE
ACTIVE
PASSIVE
PASSIVE
DA
TA
DA
TA
GR
AM
GR
AM
CO
NN
EC
TE
DC
ON
NE
CT
ED
DA
TA
GR
AM
DA
TA
GR
AM
TY
PE
O
F
CO
MM
UN
ICA
TIO
N
SE
RV
ICE
TY
PE
O
F
CO
MM
UN
ICA
TIO
N
SE
RV
ICE
COMMUNICATION DOMAINCOMMUNICATION DOMAIN
XFERXFER
sendto()/recvfrom()sendto()/recvfrom()
socket(PF_UNIX)socket(PF_UNIX)bind()/connect()bind()/connect()
socket(PF_UNIX)/bind()socket(PF_UNIX)/bind() socket(PF_INET)/bind()socket(PF_INET)/bind()
socket(PF_INET)/bind()socket(PF_INET)/bind()
sendto()/recvfrom()sendto()/recvfrom()
send()/recv()send()/recv()
socket(PF_UNIX)socket(PF_UNIX)bind()/connect()bind()/connect()
socket(PF_UNIX)socket(PF_UNIX)bind()/connect()bind()/connect()
send()/recv()send()/recv()
socket(PF_UNIX)socket(PF_UNIX)bind()/connect()bind()/connect()
socket(PF_UNIX)socket(PF_UNIX)bind()/listen()/accept()bind()/listen()/accept()
socket(PF_UNIX)socket(PF_UNIX)bind()/connect()bind()/connect()
send()/recv()send()/recv()
socket(PF_INET)socket(PF_INET)bind()/listen()/accept()bind()/listen()/accept()
socket(PF_INET)socket(PF_INET)bind()/connect()bind()/connect()
send()/recv()send()/recv()
socket(PF_UNIX)/bind()socket(PF_UNIX)/bind()
� The SocketAPI can beclassifiedalong threedimensions
Copyright c 1997-2000 Dept. of Computer Science, Washington University 14
CS 342: OO Software Development Lab OO Patterns
Problem with Sockets: Lack of Type-safetyint buggy_echo_server (u_short port_num){ // Error checking omitted.
sockaddr_in s_addr;int s_fd = socket (PF_UNIX, SOCK_DGRAM, 0);s_addr.sin_family = AF_INET;s_addr.sin_port = port_num;s_addr.sin_addr.s_addr = INADDR_ANY;
bind (s_fd, (sockaddr *) &s_addr,sizeof s_addr);
int n_fd = accept (s_fd, 0, 0);for (;;) {
char buf[BUFSIZ];ssize_t n = read (s_fd, buf, sizeof buf);if (n <= 0) break;write (n_fd, buf, n);
}}
� I/O handles arenot amenable tostrong typechecking atcompile-time
� The adjacentcode containsmany subtle,common bugs
Copyright c 1997-2000 Dept. of Computer Science, Washington University 15
CS 342: OO Software Development Lab OO Patterns
Problem with Sockets: Steep Learning Curve
Many socket/TLI API functions have complex semantics, e.g.:
� Multiple protocol families and address families
– e.g., TCP, UNIX domain, OSI, XNS, etc.
� Infrequently used features, e.g.:
– Broadcasting/multicasting– Passing open file handles– Urgent data delivery and reception– Asynch I/O, non-blocking I/O, I/O-based and timer-based event
multiplexing
Copyright c 1997-2000 Dept. of Computer Science, Washington University 16
CS 342: OO Software Development Lab OO Patterns
Problem with Sockets: Poorly Structured
sock
et()
bin
d()
con
nec
t()
list
en()
acce
pt(
)re
ad()
wri
te()
read
v()
wri
tev()
recv
()se
nd
()re
cvfr
om
()se
nd
to()
recv
msg
()se
ndm
sg()
sets
ock
op
t()
get
sock
opt(
)get
pee
rnam
e()
get
sock
nam
e()
get
host
bynam
e()
get
serv
bynam
e()
� Limitations
– Socket API is linear rather than hierarchical– There is no consistency among names...– Non-portable
Copyright c 1997-2000 Dept. of Computer Science, Washington University 17
CS 342: OO Software Development Lab OO Patterns
Problem with Sockets: Portability
� Having multiple “standards,” i.e., sockets and TLI, makes portabilitydifficult, e.g.,
– May require conditional compilation– In addition, related functions are not included in POSIX standards
� e.g., select , WaitForMultipleObjects , and poll
� Portability between UNIX and Win32 Sockets is problematic, e.g.:
– Header files– Error numbers– Handle vs. descriptor types– Shutdown semantics– I/O controls and socket options
Copyright c 1997-2000 Dept. of Computer Science, Washington University 18
CS 342: OO Software Development Lab OO Patterns
The ACE C++ IPC Wrapper Solution
IPC_SAP
A
SOCK_SAP TLI_SAP FIFO_SAPSPIPE_SAP
SOCKET
API
TRANSPORT
LAYER
INTERFACE API
STREAM PIPE
API
NAMED PIPE
API
� ACE provides C++ “wrapper facades” that encapsulate IPCprogramming interfaces like sockets and TLI
– This is an example of the Wrapper Facade Pattern
Copyright c 1997-2000 Dept. of Computer Science, Washington University 19
CS 342: OO Software Development Lab OO Patterns
Intent and Structure of the Wrapper Facade Pattern
1: method_k()
2: function_k()
clientclient
FunctionsFunctions
function_1()...function_n()
WrapperWrapperFacadeFacade
method_1()...method_m()
� Intent
– Encapsulates low-level,stand-alone systemmechanisms withintype-safe, modular, andportable class interfaces
� Forces Resolved
– Avoid tedious, error-prone,and non-portable systemAPIs
– Create cohesiveabstractions
Copyright c 1997-2000 Dept. of Computer Science, Washington University 20
CS 342: OO Software Development Lab OO Patterns
The ACE C++ Socket Wrapper Class Structure
LOCALLOCAL LOCALLOCAL//REMOTEREMOTE
ST
RE
AM
ST
RE
AM
ACTIVE
ACTIVE
PASSIVE
PASSIVE
DA
TA
DA
TA
GR
AM
GR
AM
CO
NN
EC
TE
DC
ON
NE
CT
ED
DA
TA
GR
AM
DA
TA
GR
AM
COMMUNICATION DOMAINCOMMUNICATION DOMAIN
XFERXFER
LSOCK_ConnectorLSOCK_Connector SOCK_Connector SOCK_Connector
SOCK_AcceptorSOCK_AcceptorLSOCK_AcceptorLSOCK_Acceptor
SOCK_Dgram_McastSOCK_Dgram_Mcast
LSOCK_Stream LSOCK_Stream SOCK_StreamSOCK_Stream
LSOCK_CODgram LSOCK_CODgram SOCK_CODgram SOCK_CODgram
SOCK_Dgram SOCK_Dgram LSOCK_Dgram LSOCK_Dgram
SOCK_Dgram
SOCK_Dgram
SOCK_Dgram_Bcast SOCK_Dgram_Bcast
TY
PE
O
F
CO
MM
UN
ICA
TIO
N
SE
RV
ICE
TY
PE
O
F
CO
MM
UN
ICA
TIO
N
SE
RV
ICE
CONNECTION
CONNECTION//
COMM
UNICATIO
N
COMM
UNICATIO
N
ROLEROLE
LSOCK_Dgram
LSOCK_Dgram
� Note howstand-alonefunctions arereplaced byC++ classcomponents
Copyright c 1997-2000 Dept. of Computer Science, Washington University 21
CS 342: OO Software Development Lab OO Patterns
SOCK SAP Factory Class Interfaces
class SOCK_Connector{public:
// Traitstypedef INET_Addr PEER_ADDR;typedef SOCK_Stream PEER_STREAM;
int connect(SOCK_Stream &new_sap,
const INET_Addr &raddr,Time_Value *timeout,const INET_Addr &laddr);
// ...};
class SOCK_Acceptor: public SOCK
{public:
// Traitstypedef INET_Addr PEER_ADDR;typedef SOCK_Stream PEER_STREAM;
SOCK_Acceptor(const INET_Addr &local_addr);
int accept(SOCK_Stream &new_sap,
INET_Addr *,Time_Value *);
//...};
Copyright c 1997-2000 Dept. of Computer Science, Washington University 22
CS 342: OO Software Development Lab OO Patterns
SOCK SAP Stream and Addressing Class Interfaces
class SOCK_Stream : public SOCK{public:
// Trait.typedef INET_Addr PEER_ADDR;
ssize_t send (const void *buf,int n);
ssize_t recv (void *buf,int n);
ssize_t send_n (const void *buf,int n);
ssize_t recv_n (void *buf,int n);
int close (void);// ...
};
class INET_Addr : public Addr{public:
INET_Addr (u_short port_number,const char host[]);
u_short get_port_number (void);int32 get_ip_addr (void);// ...
};
Copyright c 1997-2000 Dept. of Computer Science, Washington University 23
CS 342: OO Software Development Lab OO Patterns
OO Design Interlude
Q: Why decouple the SOCKAcceptor and the SOCKConnectorfrom SOCKStream ?
A: For the same reasons that Acceptor and Connector aredecoupled from Svc Handler , e.g.,
� A SOCKStream is only responsible for data transfer
– Regardless of whether the connection is established passively oractively
� This ensures that the SOCK* components are not used incorrectly...
– e.g., you can’t accidentally read or write onSOCKConnectors or SOCKAcceptors , etc.
Copyright c 1997-2000 Dept. of Computer Science, Washington University 24
CS 342: OO Software Development Lab OO Patterns
ACE C++ Wrapper echo server
int echo_server (u_short port_num){
// Error handling omitted.INET_Addr my_addr (port_num);SOCK_Acceptor acceptor (my_addr);SOCK_Stream new_stream;
acceptor.accept (new_stream);
for (;;){
char buf[BUFSIZ];// Error caught at compile time!ssize_t n = acceptor.recv (buf, sizeof buf);new_stream.send_n (buf, n);
}}
Copyright c 1997-2000 Dept. of Computer Science, Washington University 25
CS 342: OO Software Development Lab OO Patterns
A Generic Version of the Echo Server
template <class ACCEPTOR>int echo_server (u_short port){
// Local address of server (note use of traits).ACCEPTOR::PEER_ADDR my_addr (port);// Initialize the passive mode server.ACCEPTOR acceptor (my_addr);// Data transfer object (note use of traits).ACCEPTOR::PEER_STREAM stream;// Accept a new connection.acceptor.accept (stream);
for (;;) {char buf[BUFSIZ];ssize_t n = stream.recv (buf, sizeof buf);stream.send_n (buf, n);
}}
Copyright c 1997-2000 Dept. of Computer Science, Washington University 26
CS 342: OO Software Development Lab OO Patterns
Socket vs. ACE C++ Socket Wrapper Example� The following slides illustrate differences between using the Socket
interface vs. the ACE C++ Socket wrappers
� The example is a simple client/server “network pipe” application thatbehaves as follows:
1. Starts an iterative daemon at a well-known server port2. Client connects to the server and transmits its standard input to
the server3. The server prints this data to its standard output
� The server portion of the “network pipe” application may actually runeither locally or remotely...
Copyright c 1997-2000 Dept. of Computer Science, Washington University 27
CS 342: OO Software Development Lab OO Patterns
Network Pipe with Sockets
SERVERSERVERCLIENTCLIENT
socket()bind() (optional)
connect()
send()/recv()
socket()bind()listen()accept()
send()/recv()
2: ACTIVE
ROLE
3: SERVICE
PROCESSINGclose()
close()
NETWORK
1: PASSIVE
ROLE
Copyright c 1997-2000 Dept. of Computer Science, Washington University 28
CS 342: OO Software Development Lab OO Patterns
Network Pipe with ACE C++ Socket Wrappers
SERVERSERVERCLIENTCLIENT
SOCK_ConnectorSOCK_Stream
send()/recv()
SOCK_AcceptorSOCK_Stream
send()/recv()
2: ACTIVE
ROLE
3: SERVICE
PROCESSINGclose()
close()
NETWORK
1: PASSIVE
ROLE
Copyright c 1997-2000 Dept. of Computer Science, Washington University 29
CS 342: OO Software Development Lab OO Patterns
Running the Network Pipe Program
� e.g.,
% ./server &% echo "hello world" | ./client localhostclient localhost.cs.wustl.edu%: hello world
� Note that the ACE C++ Socket wrapper example:
– Requires much less code (about 1/2 to 2/3 less)– Provides greater clarity and less potential for errors– Operates at no loss of efficiency
� Complete example available at URL:
– www.cs.wustl.edu/�schmidt/IPC SAP-92.ps.gz
Copyright c 1997-2000 Dept. of Computer Science, Washington University 30 CS
342:
OO
Sof
twar
eD
evel
opm
entL
ab
Soc
ketC
lient
#defin
eP
OR
T_N
UM
10000
int
main
(int
arg
c,ch
ar
*arg
v[])
{st
ruct
sock
addr_
insa
ddr;
stru
cthost
ent
*hp;
char
*host
=arg
c>
1?
arg
v[1]
:"t
ango.c
s.w
ust
l.e
u_sh
ort
port
_num
=arg
c>
2hto
ns
(arg
c>
2?
ato
i(a
rgv[
2])
:P
OR
T_N
UM
);ch
ar
buf[B
UF
SIZ
];in
ts_
fd;
int
w_byt
es;
int
r_byt
es;
int
n;
/*C
reate
alo
cal
endpoin
tof
com
munic
atio
n*/
s_fd
=so
cket
(PF
_IN
ET
,S
OC
K_S
TR
EA
M,
0);
/*D
ete
rmin
eIP
addre
ssof
the
serv
er
*/hp
=geth
ost
byn
am
e(h
ost
);
Cop
yrig
htc
1997
-200
0D
ept.
ofC
ompu
ter
Sci
ence
,Was
hing
ton
Uni
vers
ity
CS 342: OO Software Development Lab
Socket Client (cont’d)
/* Set up the address information tocontact the server */
memset ((void *) &saddr, 0, sizeof saddr);saddr.sin_family = AF_INET;saddr.sin_port = port_num;memcpy (&saddr.sin_addr, hp->h_addr, hp->h_length) ;
/* Establish connection with remote server */connect (s_fd, (struct sockaddr *) &saddr,
sizeof saddr);
/* Send data to server (correctly handles"incomplete writes" due to flow control) */
while ((r_bytes = read (0, buf, sizeof buf)) > 0)for (w_bytes = 0; w_bytes < r_bytes; w_bytes += n
n = write (s_fd, buf + w_bytes, r_bytes - w_by t
/* Explicitly close the connection */close (s_fd);return 0;
}
Copyright c 1997-2000 Dept. of Computer Science, Washington University
CS 342: OO Software Development Lab
C++ Socket Wrapper Client
const u_short PORT_NUM = 10000;int main (int argc, char *argv[]){
char buf[BUFSIZ];char *host = argc > 1 ? argv[1] : "ics.uci.edu";u_short port_num =
htons (argc > 2 ? atoi (argv[2]) : PORT_NUM);
INET_Addr server_addr (port_num, host);SOCK_Stream cli_stream;SOCK_Connector connector.
// Establish the connection with server.connector.connect (cli_stream, server_addr);
Copyright c 1997-2000 Dept. of Computer Science, Washington University
CS 342: OO Software Development Lab
C++ Socket Wrapper Client (cont’d)
// Send data to server (correctly handles// "incomplete writes").
for (;;) {ssize_t r_bytes = read (0, buf, sizeof buf);cli_stream.send_n (buf, r_bytes);
}
// Explicitly close the connection.cli_stream.close ();return 0;
}
Copyright c 1997-2000 Dept. of Computer Science, Washington University
CS 342: OO Software Development Lab
Socket Server
#define PORT_NUM 10000intmain (int argc, char *argv[]){
u_short port_num =htons (argc > 1 ? atoi (argv[1]) : PORT_NUM);
struct sockaddr_in saddr;int s_fd, n_fd;
/* Create a local endpoint of communication */s_fd = socket (PF_INET, SOCK_STREAM, 0);
/* Set up the address information tobecome a server */
memset ((void *) &saddr, 0, sizeof saddr);saddr.sin_family = AF_INET;saddr.sin_port = port_num;saddr.sin_addr.s_addr = INADDR_ANY;
/* Associate address with endpoint */bind (s_fd, (struct sockaddr *) &saddr,
sizeof saddr);/* Make endpoint listen for service requests */listen (s_fd, 5);
Copyright c 1997-2000 Dept. of Computer Science, Washington University
CS 342: OO Software Development Lab
Socket Server (cont’d)
/* Performs the iterative server activities */for (;;) {
char buf[BUFSIZ];struct sockaddr_in cli_addr;int r_bytes, cli_addr_len = sizeof cli_addr;struct hostent *hp;
/* Create a new endpoint of communication */while ((n_fd = accept (s_fd, (struct sockaddr *)
&cli_addr,&cli_addr_len)) == -1
&& errno == EINTR)continue;
if (n_fd == -1)continue;
hp = gethostbyaddr ((char *) &cli_addr.sin_addr,cli_addr_len, AF_INET);
printf ("client %s: ", hp->h_name), fflush (stdo u/* Read data from client (terminate on error) */while ((r_bytes = read (n_fd, buf, sizeof buf)) >
write (1, buf, r_bytes);/* Close the new endpoint
(listening endpoint remains open) */close (n_fd);
}}
Copyright c 1997-2000 Dept. of Computer Science, Washington University
CS 342: OO Software Development Lab
C++ Wrapper Socket Server
const u_short PORT_NUM = 10000;
// SOCK_SAP Server.
intmain (int argc, char *argv[]){
u_short port_num =argc = = 1 ? PORT_NUM : ::atoi (argv[1]);
// Create a server.SOCK_Acceptor acceptor ((INET_Addr) port_num);SOCK_Stream new_stream;INET_Addr cli_addr;
Copyright c 1997-2000 Dept. of Computer Science, Washington University
CS 342: OO Software Development Lab
C++ Wrapper Socket Server (cont’d)
// Performs the iterative server activities.
for (;;) {char buf[BUFSIZ];
// Create a new SOCK_Stream endpoint (note// automatic restart if errno == EINTR).acceptor.accept (new_stream, &cli_addr);
printf ("client %s: ", cli_addr.get_host_name () )fflush (stdout);
// Read data from client (terminate on error).
for (;;) {ssize_t r_bytes;r_bytes = new_stream.recv (buf, sizeof buf);if (r_bytes <= 0) break;write (1, buf, r_bytes);
}// Close new endpoint (listening// endpoint stays open).new_stream.close ();
}
Copyright c 1997-2000 Dept. of Computer Science, Washington University
CS
342:O
OS
oftware
Developm
entLabO
OP
atterns
AC
EC
++W
rapperD
esignP
rinciples�
Enforce
typesafetyatcom
pile-time
�
Allow
controlledviolations
oftypesafety
�
Sim
plifyfor
thecom
mon
case
�
Replace
one-dimensionalinterfaces
with
hierarchicalclasscategories
�
Enhance
portabilityw
ithparam
eterizedtypes
�
Inlineperform
ancecriticalm
ethods
�
Define
auxiliaryclasses
tohide
error-pronedetails
Copyright
c
1997-2000D
ept.ofC
omputer
Science,W
ashingtonU
niversity39
CS 342: OO Software Development Lab OO Patterns
Enforce Typesafety at Compile-Time
Sockets cannot detect certain errors at compile-time, e.g.,
int s_sd = socket (PF_INET, SOCK_STREAM, 0);// ...bind (s_sd, ...); // Bind address.listen (s_sd); // Make a passive-mode socket.
// Error not detected until run-time.read (s_sd, buf, sizeof buf);
ACE enforces type-safety at compile-time via factories, e.g.:
SOCK_Acceptor acceptor (port);
// Error: recv() not a method of SOCK_Acceptor.acceptor.recv (buf, sizeof buf);
Copyright c 1997-2000 Dept. of Computer Science, Washington University 40
CS 342: OO Software Development Lab OO Patterns
Allow Controlled Violations of Typesafety
Make it easy to use the C++ Socket wrappers correctly, hard to use itincorrectly, but not impossible to use it in ways the class designers didnot anticipate
� e.g., it may be necessary to retrieve the underlying socket handle:
fd_set rd_sds;
FD_ZERO (&rd_sds);
FD_SET (acceptor.get_handle (), &rd_sds);
select (acceptor.get_handle () + 1, &rd_sds, 0, 0, 0);
Copyright c 1997-2000 Dept. of Computer Science, Washington University 41
CS 342: OO Software Development Lab OO Patterns
Supply Default Parameters
SOCK_Connector (SOCK_Stream &new_stream,const Addr &remote_sap,ACE_Time_Value *timeout = 0,const Addr &local_sap = Addr::sap_any,int protocol_family = PF_INET,int protocol = 0);
The result is extremely concise for the common case:
SOCK_Stream stream;
// Compiler supplies default values.SOCK_Connector con (stream, INET_Addr (port, host));
Copyright c 1997-2000 Dept. of Computer Science, Washington University 42
CS 342: OO Software Development Lab OO Patterns
Define Parsimonious Interfaces
e.g., use LSOCKto pass socket handles:
LSOCK_Stream stream;LSOCK_Acceptor acceptor ("/tmp/foo");
acceptor.accept (stream);stream.send_handle (stream.get_handle ());
versus
LSOCK::send_handle (const HANDLE sd) const {u_char a[2]; iovec iov; msghdr send_msg;
a[0] = 0xab, a[1] = 0xcd;iov.iov_base = (char *) a; iov.iov_len = sizeof a;send_msg.msg_iov = &iov; send_msg.msg_iovlen = 1;send_msg.msg_name = (char *) 0;send_msg.msg_namelen = 0;send_msg.msg_accrights = (char *) &sd;send_msg.msg_accrightslen = sizeof sd;return sendmsg (this->get_handle (), &send_msg, 0);
Copyright c 1997-2000 Dept. of Computer Science, Washington University 43
CS 342: OO Software Development Lab OO Patterns
Combine Multiple Operations into One Operation
Creating a conventional passive-mode socket requires multiple calls:
int s_sd = socket (PF_INET, SOCK_STREAM, 0);sockaddr_in addr;memset (&addr, 0, sizeof addr);addr.sin_family = AF_INET;addr.sin_port = htons (port);addr.sin_addr.s_addr = INADDR_ANY;bind (s_sd, &addr, addr_len);listen (s_sd);// ...
SOCKAcceptor combines this into a single operation:
SOCK_Acceptor acceptor ((INET_Addr) port);
Copyright c 1997-2000 Dept. of Computer Science, Washington University 44
CS 342: OO Software Development Lab OO Patterns
Create Hierarchical Class Categories
SOCK SOCKCODgramCODgram
LSOCK LSOCKCODgramCODgram
SOCK SOCK
A
LSOCK
AA
IPCIPCSAPSAP
AA
GROUPGROUP
COMMCOMM
DATAGRAMDATAGRAM
COMMCOMM
STREAMSTREAM
COMMCOMM
CONNECTIONCONNECTION
ESTABLISHMENTESTABLISHMENT
LSOCK LSOCKDgramDgram
SOCK SOCKDgramDgram
SOCK SOCKDgramDgramBcastBcast
LSOCK LSOCKConnectorConnector
LSOCK LSOCKAcceptorAcceptor
SOCK SOCKAcceptorAcceptor
SOCK SOCKConnectorConnector
SOCKSOCKStreamStream
LSOCKLSOCKStreamStream
SOCK SOCKDgramDgramMcastMcast
� Shared behavior is isolated in base classes
� Derived classes implement different communication services,communication domains, and connection roles
Copyright c 1997-2000 Dept. of Computer Science, Washington University 45
CS 342: OO Software Development Lab OO Patterns
Enhance Portability with Parameterized Types
OSOS KERNEL KERNEL
PROTOCOL MECHANISMSPROTOCOL MECHANISMS
((TCPTCP//IPIP,, OSI,OSI, ETC ETC.).)
USERUSER
SPACESPACE
DISTRIBUTED
APPLICATION 1
APPLICATIONAPPLICATION11 DISTRIBUTED
APPLICATION 3
APPLICATIONAPPLICATION33DISTRIBUTED
APPLICATION 2
APPLICATIONAPPLICATION22
KERNELKERNEL
SPACESPACE
BSD SOCKET
API
COMMON INTERFACECOMMON INTERFACE
((PARAMETERIZED TYPESPARAMETERIZED TYPES))
SOCKETSOCKET
API
SOCK_SAP
BSD SOCKET
API
SYSTEM VTLI API
TLI_SAP
NETWORK
INTERFACE
Copyright c 1997-2000 Dept. of Computer Science, Washington University 46
CS 342: OO Software Development Lab OO Patterns
Enhance Portability with Parameterized Types (cont’d)
Switching wholesale between sockets and TLI simply requiresinstantiating a different C++ wrapper, e.g.,
// Conditionally select IPC mechanism.#if defined (USE_SOCKETS)typedef SOCK_Acceptor PEER_ACCEPTOR;#elif defined (USE_TLI)typedef TLI_Acceptor PEER_ACCEPTOR;#endif // USE_SOCKETS.
int main (void){
// ...
// Invoke the echo_server with appropriate// network programming interfaces.echo_server<PEER_ACCEPTOR> (port);
}
Copyright c 1997-2000 Dept. of Computer Science, Washington University 47
CS 342: OO Software Development Lab OO Patterns
Inline Performance Critical Methods
Inlining is time and space efficient since key methods are very short:
class SOCK_Stream : public SOCK{public:
ssize_t send (const void *buf, size_t n){
return ACE_OS::send (this->get_handle (), buf, n);}
ssize_t recv (void *buf, size_t n){
return ACE_OS::recv (this->get_handle (), buf, n);}
};
Copyright c 1997-2000 Dept. of Computer Science, Washington University 48
CS 342: OO Software Development Lab OO Patterns
Define Auxiliary Classes to Hide Error-Prone Details
Standard C socket addressing is awkward and error-prone
� e.g., easy to neglect to zero-out a sockaddr in or convert portnumbers to network byte-order, etc.
ACE C++ Socket Wrappers define classes to handle these detailsclass INET_Addr : public Addr {public:
INET_Addr (u_short port, long ip_addr = 0) {memset (&this->inet_addr_, 0, sizeof this->inet_addr_);this->inet_addr_.sin_family = AF_INET;this->inet_addr_.sin_port = htons (port);memcpy (&this->inet_addr_.sin_addr, &ip_addr, sizeof ip_addr);
}// ...
private:sockaddr_in inet_addr_;
};
Copyright c 1997-2000 Dept. of Computer Science, Washington University 49
CS 342: OO Software Development Lab OO Patterns
Summary of ACE C++ Socket Wrapper DesignPrinciples
� Domain analysis identifies and groups related classes of existingAPI behavior
– Example subdomains include
� Local context management and options, data transfer,connection/termination handling, etc.
� Datagrams vs. streams
� Local vs. remote addressing
� Active vs. passive connection roles
� These relationships are directly reflected in the ACE C++ Socketwrapper inheritance hierarchy
Copyright c 1997-2000 Dept. of Computer Science, Washington University 50
CS 342: OO Software Development Lab OO Patterns
Summary of ACE C++ Socket Wrapper DesignPrinciples (cont’d)
� The ACE C++ Socket wrappers are designed to maximizereusability and sharing of components
– Inheritance is used to factor out commonality and decouplevariation e.g.,
� Push common services “upwards” in the inheritance hierarchy
� Factor out variations in client/server portions of socket API
� Decouple datagram vs. stream operations, local vs. remote, etc.– Inheritance also supports “functional subsetting”
� e.g., passing open file handles...
Copyright c 1997-2000 Dept. of Computer Science, Washington University 51
CS 342: OO Software Development Lab OO Patterns
Summary of ACE C++ Socket Wrapper DesignPrinciples (cont’d)
� Performance improvements techniques include:
– Inline functions are used to avoid additional function call penalties– Dynamic binding is used sparingly to reduce time/space overhead
� i.e., it is eliminated for recv /send path
� Note the difference between the composition vs.decomposition/composition aspects in design complexity
– i.e., ACE C++ Socket wrappers are primarily an exercise incomposition since the basic components already exist
– More complex OO designs involve both aspects...
� e.g., the ACE Streams, Service Configurator, and Reactorframeworks, etc.
Copyright c 1997-2000 Dept. of Computer Science, Washington University 52
CS 342: OO Software Development Lab OO Patterns
Lessons Learned Building ACE
� Good components, frameworks, and software architectures taketime to develop
� Reuse-in-the-large works best when:
– The marketplace is competitive– The domain is complex– Building middleware in-house costs too much– Corporate culture is supportive
� Produce reusable components by generalizing from workingapplications
– i.e., don’t build components in isolation
� The best components (and systems research) come from solvingreal problems
Copyright c 1997-2000 Dept. of Computer Science, Washington University 53
CS 342: OO Software Development Lab OO Patterns
Successful Application of Frameworks
Framework Framework
Tilde
FrameworkCached VirtualFilesystem
StrategyProtocol PipelineConcurrency
Expander
I/O Strategy
~/home/...
Mem
ento
Reactor/Proactor Strategy Singleton
Sta
teS
ervi
ce C
on
fig
ura
tor
Sta
te
StrategyActive ObjectPipes and Filters
Ad
apter
Service Configurator
ProtocolHandler
ProtocolFilter
Accep
tor
Event Dispatcher
Asynchronous Completion Token
� Solution Approach
– Identify sources ofcommonality andvariability
– Use patterns toidentify reusabledesign artifacts
– Use frameworksto “unify” variationin code artifacts
Copyright c 1997-2000 Dept. of Computer Science, Washington University 54
CS 342: OO Software Development Lab OO Patterns
For More Information� Overview in http://www.cs.wustl.edu/˜schmidt/ACE.html
� Header files in ˜levine/ACE_wrappers/ace , tests in tests/
� man pages in /project/adaptive/ACE_wrappers/man , e.g.,% man -M /project/adaptive/ACE_wrappers/man \
ACE_SOCK_Connector
– The man pages are generated from the header files.
� html pages inhttp://www.cs.wustl.edu/˜schmidt/ACE_wrappers/man/html/
– The html pages are generated from the man pages.
� Mail list: email subscribe ace-users [email protected]
� Newsgroup: comp.soft-sys.ace
Copyright c 1997-2000 Dept. of Computer Science, Washington University 55