ACE Examples4
ACE Examples4
ACE Examples4
Platforms change
DIAGNOSTIC
STATIONS
New design forces emerge
Distributed Object Computing Group ATM { It is essential to plan for
Computer Science Department, Washington University, St. Louis MAN
CLUSTER inevitable change
ATM IMAGE
LAN
[email protected]
STORE
http://www.cs.wustl.edu/schmidt/ACE-examples4.ps.gz
MODALITIES CENTRAL
(C T , M R , C R ) IMAGE
STORE
{ Identify sources of
Memento
State
Protocol
Expander
/home/... { Use patterns to WIDE AREA
NETWORK
{ Underlying platform dierences
identify reusable
Acceptor
design artifacts
Protocol TRANSFER
Filter
code artifacts
LOCAL AREA NETWORK
{ Emulation is necessary
2 3
ACE C++ Wrapper Tutorial ACE C++ Wrapper Tutorial
ACE framework: Resolving Syntactic Variations ACE framework: Resolving Semantic Variations
int ACE_OS::fstat (ACE_HANDLE handle, Examples int ACE_OS::clock_gettime Examples
struct stat *stp) (clockid_t clockid, struct timespec *ts)
4 5
ABSTRACTION
u_long tss_base;
several levels of
LEVEL OF
tss_base = (u_long) ts_storage; Provided by POSIX, NT OPEN/CLOSE/PUTMSG/GETMSG abstraction
t_setreg (0, PSOS_TASK_REG_TSS, tss_base); Not provided by
VxWorks, pSOS Dierent levels
void **tss_base_p = ts_storage;
STREAMS TPI are appropriate
for (u_int i = 0; Emulation in user space is NPI KERNEL for dierent tasks
i < ACE_TSS_KEYS_MAX; necessary LO FRAMEWORK DLPI SPACE
++i, ++tss_base_p)
*tss_base_p = 0; { Create a TSS emulation
return (void *) tss_base; class
#elif defined (...)
{ Provide platform-specic
// ...
method implementations
6 7
ACE C++ Wrapper Tutorial ACE C++ Wrapper Tutorial
Navigating Through the Design Alternatives Overview of DOC Middleware
Choosing the appropriate level of abstaction to program involves many IDL
IDL Helps simplify
factors
INTERFACE
INTERFACE IMPLEMENTATION
IMPLEMENTATION
REPOSITORY
REPOSITORY COMPILER
COMPILER REPOSITORY
REPOSITORY many types of
Performance in args applications
operation() OBJECT
CLIENT
{ Higher levels may be less ecient out args + return value
(SERVANT) Lets developers
work at higher
Functionality
IDL
DSI
levels of
{ Certain features, e.g., multicast, are not available at all levels DII
IDL
STUBS
ORB
SKELETON
OBJECT abstraction
INTERFACE ADAPTER
Ease of programming Examples include
{ DOC middleware is typically easier to use GIOP/IIOP ORB CORE CORBA, DCOM,
Java RMI, DCE,
Portability Sun RPC
STANDARD INTERFACE STANDARD LANGUAGE MAPPING
10 11
ACE C++ Wrapper Tutorial ACE C++ Wrapper Tutorial
Standard APIs for Network IPC Socket Taxonomy
Sockets and TLI allow ON
COMMUNICATION DOMAIN
The Socket
APPLICATION
DISTRIBUTED
PROCESS 3592
APPLICATION 1
APPLICATION
DISTRIBUTED
PROCESS4183
APPLICATION 2
APPLICATION
DISTRIBUTED
PROCESS 8729
APPLICATION 3
access to lower-level N EC
TI
LE PAS
SIV
E LOCAL LOCAL/REMOTE
API can be
IPC mechanisms, e.g.:
N
CO RO
E
classied
USER { TCP/IP AC
TIV
along three
dimensions
GRAM
SSYSTEM
YSTEM V
DATA
SOCKET
BSD
API
SOCKET
TLI API
V
IPX NetWare socket(PF_UNIX) socket(PF_INET)
protocols
API TLI API bind() sendto() bind() sendto()
{ UNIX domain
CONNECTED
STREAM DATAGRAM
socket(PF_UNIX) socket(PF_INET)
OS KERNEL KERNEL
sockets
bind() connect() recv() bind() connect() recv()
PROTOCOL SERVICES SPACE socket(PF_UNIX) socket(PF_INET)
(TCP/IP, OSI, ETC.) { OSI protocols bind() connect() send()
accept(PF_UNIX)
bind() connect() send()
accept(PF_INET)
listen() send()/recv() listen() send()/recv()
socket(PF_UNIX) bind() socket(PF_INET) bind()
NETWORK connect() send()/recv() connect() send()/recv()
INTERFACE
12 13
14 15
ACE C++ Wrapper Tutorial ACE C++ Wrapper Tutorial
Problem with Sockets: Poorly Structured Problem with Sockets: Portability
Having multiple \standards," i.e., sockets and TLI, makes portability
gethostbyname()
getservbyname()
dicult, e.g.,
getsockname()
getpeername()
getsockopt()
setsockopt()
sendmsg()
recvmsg()
connect()
accept()
writev()
readv()
listen()
write()
send()
read()
recv()
bind()
DATA
GRAM
LSOCK_Dgram SOCK_Dgram_Bcast (SOCK_Stream &new_sap, SOCK_Acceptor
SOCK_Dgram_Mcast
const INET_Addr &raddr, (const INET_Addr &local_addr);
LSOCK_Dgram SOCK_Dgram
Time_Value *timeout, int accept
const INET_Addr &laddr); (SOCK_Stream &new_sap,
LSOCK_CODgram SOCK_CODgram // ... INET_Addr *,
CONNECTED
LSOCK_Acceptor SOCK_Acceptor
}; Time_Value *);
LSOCK_Stream SOCK_Stream //...
LOCK_Connector SOCK_Connector };
STREAM DATAGRAM
LSOCK_Stream SOCK_Stream
22 23
ACE C++ Wrapper Tutorial ACE C++ Wrapper Tutorial
ACE C++ Wrapper echo server A Generic Version of the Echo Server
int echo_server (u_short port_num) template <class ACCEPTOR>
{ int echo_server (u_short port)
// Error handling omitted. {
INET_Addr my_addr (port_num); // Local address of server (note use of traits).
SOCK_Acceptor acceptor (my_addr); ACCEPTOR::PEER_ADDR my_addr (port);
SOCK_Stream new_stream; // Initialize the passive mode server.
ACCEPTOR acceptor (my_addr);
acceptor.accept (new_stream); // Data transfer object (note use of traits).
ACCEPTOR::PEER_STREAM stream;
// Accept a new connection.
for (;;)
acceptor.accept (stream);
{
char buf[BUFSIZ];
for (;;) {
// Error caught at compile time! char buf[BUFSIZ];
ssize_t n = acceptor.recv (buf, sizeof buf); ssize_t n = stream.recv (buf, sizeof buf);
new_stream.send_n (buf, n); stream.send_n (buf, n);
} }
} }
24 25
26 27
28
ACE C++ Wrapper Tutorial
Socket Client
#define PORT_NUM 10000
int
main (int argc, char *argv[]) {
ACE C++ Wrapper Tutorial
close()
struct hostent *hp;
2: ACTIVE
SOCK_Stream
CLIENT
send()/recv()
char *host = argc > 1 ? argv[1] : "tango.cs.wustl.edu";
u_short port_num = argc > 2
SOCK_Connector
NETWORK
PROCESSING
int n;
SERVER
close()
1: PASSIVE
SOCK_Stream
send()/recv()
SOCK_Acceptor
Network Pipe with ACE C++ Socket Wrappers
30
29
saddr.sin_port = port_num;
memcpy (&saddr.sin_addr, hp->h_addr, hp->h_length);
close (s_fd);
{ Provides greater clarity and less potential for errors
return 0;
}
Running the Network Pipe Program
31
ACE C++ Wrapper Tutorial ACE C++ Wrapper Tutorial
Socket Server C++ Socket Wrapper Client
#define PORT_NUM 10000 const u_short PORT_NUM = 10000;
int int main (int argc, char *argv[])
main (int argc, char *argv[]) {
{ char buf[BUFSIZ];
u_short port_num = char *host = argc > 1 ? argv[1] : "ics.uci.edu";
htons (argc > 1 ? atoi (argv[1]) : PORT_NUM); u_short port_num =
struct sockaddr_in saddr; htons (argc > 2 ? atoi (argv[2]) : PORT_NUM);
int s_fd, n_fd;
INET_Addr server_addr (port_num, host);
/* Create a local endpoint of communication */ SOCK_Stream cli_stream;
s_fd = socket (PF_INET, SOCK_STREAM, 0); SOCK_Connector connector.
/* Set up the address information to // Establish the connection with server.
become a server */ connector.connect (cli_stream, server_addr);
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);
34 32
ACE C++ Wrapper Tutorial ACE C++ Wrapper Tutorial
Socket Server (cont'd) C++ Socket Wrapper Client (cont'd)
/* Performs the iterative server activities */ // Send data to server (correctly handles
for (;;) { // "incomplete writes").
char buf[BUFSIZ];
struct sockaddr_in cli_addr; for (;;) {
int r_bytes, cli_addr_len = sizeof cli_addr; ssize_t r_bytes = read (0, buf, sizeof buf);
struct hostent *hp; cli_stream.send_n (buf, r_bytes);
}
/* Create a new endpoint of communication */
while ((n_fd = accept (s_fd, (struct sockaddr *) // Explicitly close the connection.
&cli_addr, cli_stream.close ();
&cli_addr_len)) == -1 return 0;
&& 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 (stdout);
/* Read data from client (terminate on error) */
while ((r_bytes = read (n_fd, buf, sizeof buf)) > 0)
write (1, buf, r_bytes);
/* Close the new endpoint
(listening endpoint remains open) */
close (n_fd);
}
}
35 33
38
int
main (int argc, char *argv[])
{
u_short port_num =
argc == 1 ? PORT_NUM : ::atoi (argv[1]);
Simplify for the common case
// Create a server.
SOCK_Acceptor acceptor ((INET_Addr) port_num);
Enforce typesafety at compile-time
SOCK_Stream new_stream;
INET_Addr cli_addr;
Allow controlled violations of typesafety
39
ACE C++ Wrapper Tutorial
// ...
C++ Wrapper Socket Server (cont'd)
// Performs the iterative server activities.
for (;;) {
char buf[BUFSIZ];
40 41
42 43
ACE C++ Wrapper Tutorial ACE C++ Wrapper Tutorial
Create Hierarchical Class Categories Enhance Portability with Parameterized Types
A A
IPC SOCK
SAP
DISTRIBUTED
APPLICATION1 DISTRIBUTED
APPLICATION2 DISTRIBUTED
APPLICATION3
APPLICATION 1 APPLICATION 2 APPLICATION 3
SOCK
COMMON INTERFACE
SOCK SOCK SOCK SOCK SOCK
Dgram Dgram CODgram Stream Connector Acceptor (PARAMETERIZED TYPES)
Bcast
SOCK_SAP TLI_SAP
SOCK
Dgram
LSOCK
Dgram
LSOCK
CODgram
LSOCK
Stream
LSOCK
Connector
LSOCK
Acceptor
BSD SOCKET
SOCKET SBSD
YSTEM V
SOCKET
USER
Mcast SPACE
API
API TLIAPIAPI
GROUP DATAGRAM A STREAM CONNECTION
COMM COMM COMM ESTABLISHMENT
LSOCK
OS KERNEL
KERNEL
PROTOCOL MECHANISMS
Shared behavior is isolated in base classes (TCP/IP, OSI, ETC.)
SPACE
44 45
46 47
ACE C++ Wrapper Tutorial ACE C++ Wrapper Tutorial
Dene Auxiliary Classes to Hide Error-Prone Details Summary of ACE C++ Socket Wrapper Design
Standard C socket addressing is awkward and error-prone Principles
e.g., easy to neglect to zero-out a sockaddr in or convert port
Domain analysis identies and groups related classes of existing API
numbers to network byte-order, etc.
behavior
ACE C++ Socket Wrappers dene classes to handle these details { Example subdomains include
class INET_Addr : public Addr { Local context management and options, data transfer,
public:
INET_Addr (u_short port, long ip_addr = 0) {
connection/termination handling, etc.
memset (&this->inet_addr_, 0, sizeof this->inet_addr_); Datagrams vs. streams
this->inet_addr_.sin_family = AF_INET; Local vs. remote addressing
this->inet_addr_.sin_port = htons (port);
memcpy (&this->inet_addr_.sin_addr, &ip_addr, sizeof ip_addr); Active vs. passive connection roles
}
// ...
private: These relationships are directly re
ected in the ACE C++ Socket
sockaddr_in inet_addr_; wrapper inheritance hierarchy
};
48 49
50 51
ACE C++ Wrapper Tutorial
Concluding Remarks
52