diff options
Diffstat (limited to 'ACE/examples/IPC_SAP')
86 files changed, 9498 insertions, 0 deletions
diff --git a/ACE/examples/IPC_SAP/ATM_SAP/CPP-client.cpp b/ACE/examples/IPC_SAP/ATM_SAP/CPP-client.cpp new file mode 100644 index 00000000000..e4f10eb27b0 --- /dev/null +++ b/ACE/examples/IPC_SAP/ATM_SAP/CPP-client.cpp @@ -0,0 +1,202 @@ +// $Id$ + +#include "ace/OS_main.h" +#include "ace/ATM_Connector.h" +#include "ace/ATM_Addr.h" +#include "ace/High_Res_Timer.h" +#include "ace/Log_Msg.h" + +ACE_RCSID(ATM_SAP, CPP_client, "$Id$") + +#if defined (ACE_HAS_ATM) + +#define MAX_LEAVES 32 + +/* ACE_ATM Client */ + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if ( argc < 2 ) + ACE_ERROR_RETURN ((LM_ERROR, + "Usage: %s <rate> <PDU> <session> <host> <selector> [ host sel ] ...\n" + "\tUse 0 for default values\n", + argv[0]), + 1); + + int rate = ACE_OS::atoi( argv[ 1 ]); + rate = ( rate != 0 ) ? rate : 170000; + int pdu_size = ACE_OS::atoi( argv[ 2 ]) * 1024; + pdu_size = ( pdu_size != 0 ) ? pdu_size : 8192; + int session = ACE_OS::atoi( argv[ 3 ]); + session = ( session != 0 ) ? session : 100; + + ACE_OS::printf( "ATM_Client: rate: %d c/s, PDU: %dB, session: %d pkts\n", + rate, pdu_size, session ); + + // Record all hosts/selectors + ACE_ATM_Addr hosts[ MAX_LEAVES ]; + int num_leaves = argc / 2 - 2; + + ACE_OS::printf( "ATM_Client: Connecting to ...\n" ); + for ( int i = 0; i < num_leaves; i++ ) { + hosts[ i ].set( argv[ i*2 + 4 ], + ( argv[ i*2 + 5 ] != 0 ) + ? ACE_OS::atoi( argv[ i*2 + 5 ]) : ACE_ATM_Addr::DEFAULT_SELECTOR ); + ACE_OS::printf( "ATM_Client: leaf: %s (%s), sel: %d\n", + argv[ i*2 + 4 ], + hosts[ i ].addr_to_string(), + hosts[ i ].get_selector()); + } + + // The timeout really gets ignored since FORE's drivers don't work when + // ioctl or fcntl calls are made on the transport id/file descriptor + int timeout = ACE_DEFAULT_TIMEOUT; + char buf[BUFSIZ]; + ACE_ATM_Stream atm_stream; + + char hostname[ MAXNAMELEN ]; + ACE_OS::hostname( hostname, MAXNAMELEN ); + ACE_ATM_Addr local_addr( hostname, hosts[ 0 ].get_selector()); + + ACE_OS::printf( "ATM_Client: local host: %s(%s)\n", + hostname, local_addr.addr_to_string()); + + // In order to construct connections options the file handle is + // needed. Therefore, we need to open the ATM_Stream before we + // construct the options. + ACE_OS::printf( "ATM_Client: to open a stream\n" ); + if (atm_stream.open () == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "open failed"), + 1); + + ACE_DEBUG ((LM_DEBUG, + "ATM_Client: starting non-blocking connection\n")); + + // Initiate timed, non-blocking connection with server. + ACE_ATM_Connector con; + + // Construct QoS options - currently FORE only supports bandwidth + ACE_OS::printf( "ATM_Client: specify cell rate at %d c/s\n", rate ); + ACE_ATM_QoS qos; + qos.set_rate(atm_stream.get_handle (), + rate, + ACE_ATM_QoS::OPT_FLAGS_CPID); + + if ( num_leaves == 1 ) { + // Point-to-point connection + // Not sure why but reuse_addr set to true/1 causes problems for + // FORE/XTI/ATM - this is now handled in ACE_ATM_Connector::connect() + ACE_OS::printf( "ATM_Client: to open a connection \n" ); + ACE_ATM_Params params = ACE_ATM_Params(); + if (con.connect (atm_stream, + hosts[ 0 ], + params, + qos, + (ACE_Time_Value *) &ACE_Time_Value::zero, + local_addr, + 0, + 0 ) == -1) { + if (errno != EWOULDBLOCK) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "ATM_Client: connection failed"), + 1); + + ACE_DEBUG ((LM_DEBUG, + "ATM_Client: starting timed connection\n")); + + // Check if non-blocking connection is in progress, and wait up + // to timeout seconds for it to complete. + ACE_Time_Value tv (timeout); + + ACE_OS::printf( "ATM_Client: connection completed\n" ); + if (con.complete (atm_stream, + &hosts[ 0 ], + &tv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "ATM_Client: connection failed"), + 1); + else + ACE_DEBUG ((LM_DEBUG, + "ATM_Client: connected to %s\n", + hosts[ 0 ].addr_to_string())); + } + } else { + // Point-to-multipoint connection + for ( int i = 0; i < num_leaves; i++ ) { + con.add_leaf( atm_stream, + hosts[ i ], + i, + 0 ); + + } + } /* if num_leaves == 1 */ + + ACE_UINT16 vpi, vci; + atm_stream.get_vpi_vci(vpi, vci); + ACE_DEBUG ((LM_DEBUG, + "ATM_Client: connected to VPI %d VCI %d\n", + vpi, vci)); + + // Send data to server (correctly handles "incomplete writes"). + + int s_bytes; + int total; + int xmit = 0; + ACE_High_Res_Timer timer; + ACE_Time_Value elapsed; + double real_time; + double actual_rate; + + for ( ;; ) { + total = 0; + + timer.start_incr(); + + for ( ;; ) { + s_bytes = atm_stream.send_n( buf, BUFSIZ, 0 ); + if ( s_bytes == -1 ) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "send_n"), + 1); + + total += s_bytes; + + if ( total >= session * pdu_size ) + break; + } + + timer.stop_incr(); + timer.elapsed_time_incr( elapsed ); + real_time = elapsed.sec() * ACE_ONE_SECOND_IN_USECS + elapsed.usec(); + xmit += total; + actual_rate = ( double )xmit * ( double )8 / real_time; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) bytes = %d, usec = %f, rate = %0.00f Mbps\n"), + xmit, + real_time, + actual_rate < 0 ? 0 : actual_rate )); + } + + // Explicitly close the connection. + ACE_OS::printf( "ATM_Client: close connection\n" ); + if (atm_stream.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "close"), + -1); + return 0; +} +#else +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "your platform isn't configured to support ATM\n"), + 1); +} +#endif /* ACE_HAS_ATM */ diff --git a/ACE/examples/IPC_SAP/ATM_SAP/CPP-server.cpp b/ACE/examples/IPC_SAP/ATM_SAP/CPP-server.cpp new file mode 100644 index 00000000000..8cf6e9c9c92 --- /dev/null +++ b/ACE/examples/IPC_SAP/ATM_SAP/CPP-server.cpp @@ -0,0 +1,156 @@ +// $Id$ + +#include "ace/OS_main.h" +#include "ace/ATM_Acceptor.h" +#include "ace/ATM_Addr.h" +#include "ace/High_Res_Timer.h" +#include "ace/Log_Msg.h" + +ACE_RCSID(ATM_SAP, CPP_ATM_server, "$Id$") + +#if defined (ACE_HAS_ATM) +// ACE_ATM Server + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT); + + //unsigned char selector = ACE_ATM_Addr::DEFAULT_SELECTOR; + //int selector_specified = 0; + + if (argc > 2) + ACE_ERROR_RETURN ((LM_ERROR, + "Usage: %s [selector]\n", + argv[0]), + 1); + + // Create a server address. + ACE_ATM_Addr addr; + //if (selector_specified) + unsigned char selector = ( argc == 2 ) ? ACE_OS::atoi( argv[ 1 ]) : ACE_ATM_Addr::DEFAULT_SELECTOR; + addr.set_selector( selector ); + ACE_OS::printf( "ATM_Server: selector changed to %d\n", addr.get_selector()); + + + // Create a server, reuse the addr. + ACE_ATM_Acceptor peer_acceptor; + ACE_ATM_Params params; + + // Not sure why but reuse_addr set to true/1 causes problems for + // FORE/XTI/ATM - this is now handled in ACE_ATM_Acceptor::open() + + ACE_HANDLE ret = peer_acceptor.open (addr, 5, params); + if ( ret == ACE_INVALID_HANDLE ) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "open"), + -1); + + ACE_ATM_Stream new_stream; + ACE_ATM_Addr local_addr; + + local_addr.set_selector( selector ); + peer_acceptor.get_local_addr( local_addr ); + + ACE_DEBUG ((LM_DEBUG, + "starting server at address %s\n", + local_addr.addr_to_string ())); + + // Performs the iterative server activities + char buf[BUFSIZ]; + ACE_High_Res_Timer timer; + int total; + ACE_Time_Value tv; + double real_time; + double actual_rate; + + for (;;) { + // Create a new ACE_ATM_Stream endpoint (note automatic restart + // if errno == EINTR). + ACE_OS::printf( "ATM_Server: expecting clients\n" ); + + if (peer_acceptor.accept (new_stream, + &addr, + &timeout) == -1) { + ACE_ERROR ((LM_ERROR, + "%p\n", + "accept")); + continue; + } + + ACE_OS::printf( "ATM_Server: got a connection\n" ); + + ACE_UINT16 vpi, vci; + vpi = vci = 0; + // This has problem on PMP connections on NT + //new_stream.get_vpi_vci(vpi, vci); + ACE_DEBUG ((LM_DEBUG, + "connected to VPI %d VCI %d\n", + vpi, vci)); + + ACE_OS::printf( "ATM_Server: connection accepted\n" ); + + ACE_DEBUG ((LM_DEBUG, + "client %s connected\n", + addr.addr_to_string ())); + ACE_DEBUG ((LM_DEBUG, + "client %s connected to host\n", + new_stream.get_peer_name ())); + + // Read data from client (terminate on error). + + int recvd = 0; + + for ( ;; ) { + total = 0; + timer.start_incr(); + + for (int r_bytes; + (r_bytes = new_stream.recv (buf, sizeof buf, 0)) > 0; ) { +// ACE_OS::printf( "ATM_Server: received %dB\n", r_bytes ); + +// if (ACE_OS::write (ACE_STDOUT, +// buf, +// r_bytes) != r_bytes) +// ACE_ERROR ((LM_ERROR, +// "%p\n", +// "ACE::send_n")); + total += r_bytes; + + if ( total > 10000000 ) + break; + + } + + timer.stop_incr(); + timer.elapsed_time_incr( tv ); + real_time = tv.sec() * ACE_ONE_SECOND_IN_USECS + tv.usec(); + recvd += total; + actual_rate = ( double )recvd * ( double )8 / real_time; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) bytes = %d, usec = %f, rate = %0.00f Mbps\n"), + recvd, + real_time, + actual_rate < 0 ? 0 : actual_rate )); + } + + // Close new endpoint (listening endpoint stays open). + if (new_stream.close () == -1) + ACE_ERROR ((LM_ERROR, + "%p\n", + "close")); + } + + /* NOTREACHED */ + return 0; +} +#else +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "your platform isn't configured to support ATM\n"), + 1); +} +#endif /* ACE_HAS_ATM */ diff --git a/ACE/examples/IPC_SAP/ATM_SAP/Makefile.am b/ACE/examples/IPC_SAP/ATM_SAP/Makefile.am new file mode 100644 index 00000000000..45504c71ea1 --- /dev/null +++ b/ACE/examples/IPC_SAP/ATM_SAP/Makefile.am @@ -0,0 +1,48 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +## Makefile.atm_sap_client.am + +noinst_PROGRAMS = client + +client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +client_SOURCES = \ + CPP-client.cpp + +client_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.atm_sap_server.am + +noinst_PROGRAMS += server + +server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +server_SOURCES = \ + CPP-server.cpp + +server_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/IPC_SAP/ATM_SAP/atm_sap.mpc b/ACE/examples/IPC_SAP/ATM_SAP/atm_sap.mpc new file mode 100644 index 00000000000..d0f716bb764 --- /dev/null +++ b/ACE/examples/IPC_SAP/ATM_SAP/atm_sap.mpc @@ -0,0 +1,16 @@ +// -*- MPC -*- +// $Id$ + +project(*client) : aceexe { + exename = client + Source_Files { + CPP-client.cpp + } +} + +project(*server) : aceexe { + exename = server + Source_Files { + CPP-server.cpp + } +}
\ No newline at end of file diff --git a/ACE/examples/IPC_SAP/DEV_SAP/Makefile.am b/ACE/examples/IPC_SAP/DEV_SAP/Makefile.am new file mode 100644 index 00000000000..ecc65507d22 --- /dev/null +++ b/ACE/examples/IPC_SAP/DEV_SAP/Makefile.am @@ -0,0 +1,14 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +SUBDIRS = \ + reader \ + writer + diff --git a/ACE/examples/IPC_SAP/DEV_SAP/README b/ACE/examples/IPC_SAP/DEV_SAP/README new file mode 100644 index 00000000000..8e47d8c5cec --- /dev/null +++ b/ACE/examples/IPC_SAP/DEV_SAP/README @@ -0,0 +1,23 @@ +This directory contains a test example for the DEV_SAP +class category. It implements a class TTY_IO that is +derived from ACE_DEV_IO and adds a control method +with specific features for a serial line connection +(e.g. /dev/ttya and /dev/ttyb on UNIX systems). + +The reader/reader executable initializes its +device-special file (given as command-line parameter), +reads characters from it (until it recognizes character 'q') +ands sends the characters read to stdout. + +The writer/writer executable also initializes its +device-special file (given as command-line parameter), +reads characters from stdin (until'q') and sends them +to the device. + +To run the tests I connect /dev/ttya and /dev/ttyb (with a +zero modem cable) and start the reader with "reader /dev/ttya" +and the writer (in a different window) with "writer /dev/ttyb". + +Characters typed in the writer window should now appear as output +in the reader window. Note that characters are buffered till EOL. + diff --git a/ACE/examples/IPC_SAP/DEV_SAP/reader/Makefile.am b/ACE/examples/IPC_SAP/DEV_SAP/reader/Makefile.am new file mode 100644 index 00000000000..ebd4eb798b8 --- /dev/null +++ b/ACE/examples/IPC_SAP/DEV_SAP/reader/Makefile.am @@ -0,0 +1,39 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + + +## Makefile.dev_sap_reader.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS = reader + +reader_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +reader_SOURCES = \ + reader.cpp + +reader_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/IPC_SAP/DEV_SAP/reader/dev_sap_reader.mpc b/ACE/examples/IPC_SAP/DEV_SAP/reader/dev_sap_reader.mpc new file mode 100644 index 00000000000..a6535c82e82 --- /dev/null +++ b/ACE/examples/IPC_SAP/DEV_SAP/reader/dev_sap_reader.mpc @@ -0,0 +1,11 @@ +// -*- MPC -*- +// $Id$ + +project : aceexe { + avoids += ace_for_tao + exename = reader + Source_Files { + reader.cpp + } +} + diff --git a/ACE/examples/IPC_SAP/DEV_SAP/reader/reader.cpp b/ACE/examples/IPC_SAP/DEV_SAP/reader/reader.cpp new file mode 100644 index 00000000000..60bfa446c2f --- /dev/null +++ b/ACE/examples/IPC_SAP/DEV_SAP/reader/reader.cpp @@ -0,0 +1,72 @@ +// $Id$ + +#include "ace/DEV_Addr.h" +#include "ace/DEV_Connector.h" +#include "ace/TTY_IO.h" + +ACE_RCSID(reader, reader, "$Id$") + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc < 2) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("usage: %s device-filename\n"), + argv[0]), + 1); + + ACE_TTY_IO read_dev; + ACE_DEV_Connector con; + + if (con.connect (read_dev, + ACE_DEV_Addr (argv[1])) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + argv[1]), + 1); + + ACE_TTY_IO::Serial_Params myparams; + myparams.baudrate = 19200; + myparams.xonlim = 0; + myparams.xofflim = 0; + myparams.readmincharacters = 0; + myparams.readtimeoutmsec = 10*1000; // 10 seconds + myparams.paritymode = "EVEN"; + myparams.ctsenb = false; + myparams.rtsenb = 0; + myparams.xinenb = false; + myparams.xoutenb = false; + myparams.modem = false; + myparams.rcvenb = true; + myparams.dsrenb = false; + myparams.dtrdisable = false; + myparams.databits = 8; + myparams.stopbits = 1; + + if (read_dev.control (ACE_TTY_IO::SETPARAMS, + &myparams) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p control\n"), + argv[1]), + 1); + + // Read till character 'q'. + for (char readback = 'x'; readback != 'q'; ) + { + ssize_t bytes_read = + read_dev.recv ((void *) &readback, 1); + + if (bytes_read == 1) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("read: %c\n"), + readback)); + else if (bytes_read == 0) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("timeout!\n"))); + else if (bytes_read == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p recv\n"), + argv[1]), 1); + } + + return 0; +} diff --git a/ACE/examples/IPC_SAP/DEV_SAP/writer/Makefile.am b/ACE/examples/IPC_SAP/DEV_SAP/writer/Makefile.am new file mode 100644 index 00000000000..b660839e482 --- /dev/null +++ b/ACE/examples/IPC_SAP/DEV_SAP/writer/Makefile.am @@ -0,0 +1,39 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + + +## Makefile.dev_sap_writer.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS = writer + +writer_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +writer_SOURCES = \ + writer.cpp + +writer_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/IPC_SAP/DEV_SAP/writer/dev_sap_writer.mpc b/ACE/examples/IPC_SAP/DEV_SAP/writer/dev_sap_writer.mpc new file mode 100644 index 00000000000..75486584b6d --- /dev/null +++ b/ACE/examples/IPC_SAP/DEV_SAP/writer/dev_sap_writer.mpc @@ -0,0 +1,11 @@ +// -*- MPC -*- +// $Id$ + +project : aceexe { + avoids += ace_for_tao + exename = writer + Source_Files { + writer.cpp + } +} + diff --git a/ACE/examples/IPC_SAP/DEV_SAP/writer/writer.cpp b/ACE/examples/IPC_SAP/DEV_SAP/writer/writer.cpp new file mode 100644 index 00000000000..a61b8ca2b8d --- /dev/null +++ b/ACE/examples/IPC_SAP/DEV_SAP/writer/writer.cpp @@ -0,0 +1,77 @@ +// $Id$ + +#include "ace/DEV_Connector.h" +#include "ace/TTY_IO.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID(writer, writer, "$Id$") + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc < 2) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("usage: %s device-filename\n"), + argv[0]), 1); + + ACE_TTY_IO write_dev; + ACE_DEV_Connector con; + + if (con.connect (write_dev, + ACE_DEV_Addr (argv[1])) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + argv[1]), + 1); + + ACE_TTY_IO::Serial_Params myparams; + myparams.baudrate = 19200; + myparams.xonlim = 0; + myparams.xofflim = 0; + myparams.readmincharacters = 0; + myparams.readtimeoutmsec = 10000; + myparams.paritymode = "EVEN"; + myparams.ctsenb = false; + myparams.rtsenb = 0; + myparams.xinenb = false; + myparams.xoutenb = false; + myparams.modem = false; + myparams.rcvenb = true; + myparams.dsrenb = false; + myparams.dtrdisable = false; + myparams.databits = 8; + myparams.stopbits = 1; + + if (write_dev.control (ACE_TTY_IO::SETPARAMS, + &myparams) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("control")), + 1); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("enter character to send, q terminates :\n"))); + + for (char writeto; + ACE_OS::read (ACE_STDIN, &writeto, 1) != -1; + ) + { + ssize_t bytes_written = + write_dev.send_n ((void *) &writeto, + 1); + + if (bytes_written != 1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("send")), + 1); + if (writeto == 'q') + break; + } + + if (write_dev.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("close")), + 1); + return 0; +} diff --git a/ACE/examples/IPC_SAP/FIFO_SAP/FIFO-Msg-client.cpp b/ACE/examples/IPC_SAP/FIFO_SAP/FIFO-Msg-client.cpp new file mode 100644 index 00000000000..408ac3af4e1 --- /dev/null +++ b/ACE/examples/IPC_SAP/FIFO_SAP/FIFO-Msg-client.cpp @@ -0,0 +1,43 @@ +// $Id$ + +#include "ace/FIFO_Send_Msg.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_main.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_time.h" +#include "ace/OS_NS_string.h" + +ACE_RCSID(FIFO_SAP, FIFO_Msg_client, "$Id$") + +#if defined (ACE_HAS_STREAM_PIPES) + +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_FIFO_Send_Msg client (ACE_DEFAULT_RENDEZVOUS); + + char buf[BUFSIZ]; + ACE_Str_Buf msg (buf); + + ACE_OS::srand (unsigned (ACE_OS::time (0))); + + while (ACE_OS::fgets (buf, sizeof buf, stdin) != 0) + { + msg.len = ACE_OS::strlen (buf) + 1; + if (client.send (ACE_OS::rand () % 11, &msg) == -1) + ACE_OS::perror ("send"); + } + + if (client.close () == -1) + ACE_OS::perror ("close"), ACE_OS::exit (1); + + return 0; +} +#else +#include "ace/os_include/os_stdio.h" +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::fprintf (stderr, "This feature is not supported\n"); + return 0; +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/ACE/examples/IPC_SAP/FIFO_SAP/FIFO-Msg-server.cpp b/ACE/examples/IPC_SAP/FIFO_SAP/FIFO-Msg-server.cpp new file mode 100644 index 00000000000..fc96ec71dbb --- /dev/null +++ b/ACE/examples/IPC_SAP/FIFO_SAP/FIFO-Msg-server.cpp @@ -0,0 +1,49 @@ +// $Id$ + +#include "ace/FIFO_Recv_Msg.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_stropts.h" +#include "ace/OS_main.h" + +ACE_RCSID(FIFO_SAP, FIFO_Msg_server, "$Id$") + +#if defined (ACE_HAS_STREAM_PIPES) + +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::unlink (ACE_DEFAULT_RENDEZVOUS); + ACE_FIFO_Recv_Msg server (ACE_DEFAULT_RENDEZVOUS); + char buf[BUFSIZ]; + ACE_Str_Buf msg (buf, 0, sizeof buf); + int flags = MSG_ANY; + int band = 0; + int n; + + while ((n = server.recv (&band, &msg, (ACE_Str_Buf *) 0, &flags)) >= 0) + { + if (msg.len == 0) + break; + else + ACE_DEBUG ((LM_DEBUG, "%4d (%4d): %*s", + msg.len, band, msg.len, msg.buf)); + flags = MSG_ANY; + band = 0; + } + + if (n == -1) + ACE_OS::perror ("recv"), ACE_OS::exit (1); + + return 0; +} +#else +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR ((LM_INFO, + ACE_TEXT ("This feature is not supported\n"))); + return 0; +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/ACE/examples/IPC_SAP/FIFO_SAP/FIFO-client.cpp b/ACE/examples/IPC_SAP/FIFO_SAP/FIFO-client.cpp new file mode 100644 index 00000000000..8c80809f380 --- /dev/null +++ b/ACE/examples/IPC_SAP/FIFO_SAP/FIFO-client.cpp @@ -0,0 +1,29 @@ +// $Id$ + +#include "ace/FIFO_Send.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_main.h" + +ACE_RCSID(FIFO_SAP, FIFO_client, "$Id$") + +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_FIFO_Send client (ACE_DEFAULT_RENDEZVOUS); + ACE_TCHAR buf[BUFSIZ]; + + while (ACE_OS::fgets (buf, sizeof buf, stdin) != 0) + { + ssize_t n = ACE_OS::strlen (buf); + + if (client.send (buf, n) != n) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), 1); + } + + if (client.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), 1); + + return 0; +} diff --git a/ACE/examples/IPC_SAP/FIFO_SAP/FIFO-server.cpp b/ACE/examples/IPC_SAP/FIFO_SAP/FIFO-server.cpp new file mode 100644 index 00000000000..4cd32c03449 --- /dev/null +++ b/ACE/examples/IPC_SAP/FIFO_SAP/FIFO-server.cpp @@ -0,0 +1,30 @@ +// $Id$ + +#include "ace/FIFO_Recv.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_main.h" + +ACE_RCSID(FIFO_SAP, FIFO_server, "$Id$") + +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::unlink (ACE_DEFAULT_RENDEZVOUS); + ACE_FIFO_Recv server (ACE_DEFAULT_RENDEZVOUS); + char buf[BUFSIZ]; + int n; + + while ((n = server.recv (buf, sizeof buf)) > 0) + { + ACE_OS::printf ("%4d: ", n); + ACE_OS::fflush (stdout); + ACE_OS::write (ACE_STDOUT, buf, n); + } + + if (n == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "recv"), 1); + + return 0; +} diff --git a/ACE/examples/IPC_SAP/FIFO_SAP/FIFO-test.cpp b/ACE/examples/IPC_SAP/FIFO_SAP/FIFO-test.cpp new file mode 100644 index 00000000000..d6911908658 --- /dev/null +++ b/ACE/examples/IPC_SAP/FIFO_SAP/FIFO-test.cpp @@ -0,0 +1,122 @@ +// $Id$ + +// Purpose: This program uses ACE_FIFO wrappers to perform +// interprocess communication between a parent process and a child +// process. The parents reads from an input file and writes it into +// the fifo. The child reads from the ACE_FIFO and executes the more +// command. + +#include "ace/FIFO_Recv.h" +#include "ace/FIFO_Send.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_sys_wait.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_fcntl.h" + +ACE_RCSID(FIFO_SAP, FIFO_test, "$Id$") + +#define PERMS 0666 +#define EXEC_NAME "more" +#define EXEC_COMMAND_ARG "more" + +static const ACE_TCHAR *FIFO_NAME = ACE_TEXT ("/tmp/fifo"); + +static int +do_child (ACE_FIFO_Recv &fifo_reader) +{ + // Set child's stdin to read from the fifo. + if (ACE_OS::close (ACE_STDIN) == -1 + || ACE_OS::dup (fifo_reader.get_handle ()) == ACE_INVALID_HANDLE) + return -1; + + char *argv[2]; + argv[0] = const_cast<char *> (EXEC_COMMAND_ARG); + argv[1] = 0; + + if (ACE_OS::execvp (EXEC_NAME, argv) == -1) + return -1; + return 0; +} + +static int +do_parent (const ACE_TCHAR fifo_name[], + ACE_TCHAR input_filename[]) +{ + ACE_FIFO_Send fifo_sender (fifo_name, O_WRONLY | O_CREAT); + ssize_t len; + char buf[BUFSIZ]; + + if (fifo_sender.get_handle () == ACE_INVALID_HANDLE) + return -1; + + ACE_HANDLE inputfd = + ACE_OS::open (input_filename, O_RDONLY); + + if (inputfd == ACE_INVALID_HANDLE) + return -1; + + // Read from input file and write into input end of the fifo. + + while ((len = ACE_OS::read (inputfd, buf, sizeof buf)) > 0) + if (fifo_sender.send (buf, len) != len) + return -1; + + if (len == -1) + return -1; + + if (fifo_sender.remove () == -1) + return -1; + return 0; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_LOG_MSG->open (argv[0]); + + if (argc != 2) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("usage: %n input-file\n"), + 1)); + ACE_OS::exit (1); + } + + ACE_FIFO_Recv fifo_reader (FIFO_NAME, O_RDONLY | O_CREAT, PERMS, 0); + + if (fifo_reader.get_handle () == ACE_INVALID_HANDLE) + return -1; + + pid_t child_pid = ACE_OS::fork (); + + switch (child_pid) + { + case -1: + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%n: %p\n%a"), + ACE_TEXT ("fork"), + 1)); + case 0: + if (do_child (fifo_reader) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%n: %p\n%a"), + ACE_TEXT ("do_child"), + 1)); + default: + if (do_parent (FIFO_NAME, argv[1]) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%n: %p\n%a"), + ACE_TEXT ("do_parent"), + 1)); + + // wait for child to ACE_OS::exit. + if (ACE_OS::waitpid (child_pid, (ACE_exitcode *) 0, 0) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%n: %p\n%a"), + ACE_TEXT ("waitpid"), + 1)); + } + + return 0; +} diff --git a/ACE/examples/IPC_SAP/FIFO_SAP/Makefile.am b/ACE/examples/IPC_SAP/FIFO_SAP/Makefile.am new file mode 100644 index 00000000000..b207926d2c8 --- /dev/null +++ b/ACE/examples/IPC_SAP/FIFO_SAP/Makefile.am @@ -0,0 +1,103 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + + +## Makefile.Fifo_Sap_Msg_Client.am + +noinst_PROGRAMS = FIFO-Msg-client + +FIFO_Msg_client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +FIFO_Msg_client_SOURCES = \ + FIFO-Msg-client.cpp + +FIFO_Msg_client_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Fifo_Sap_Msg_Server.am + +noinst_PROGRAMS += FIFO-Msg-server + +FIFO_Msg_server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +FIFO_Msg_server_SOURCES = \ + FIFO-Msg-server.cpp + +FIFO_Msg_server_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.fifo_sap_client.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += FIFO-client + +FIFO_client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +FIFO_client_SOURCES = \ + FIFO-client.cpp + +FIFO_client_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.fifo_sap_server.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += FIFO-server + +FIFO_server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +FIFO_server_SOURCES = \ + FIFO-server.cpp + +FIFO_server_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.fifo_sap_test.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += FIFO-test + +FIFO_test_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +FIFO_test_SOURCES = \ + FIFO-test.cpp + +FIFO_test_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/IPC_SAP/FIFO_SAP/fifo_sap.mpc b/ACE/examples/IPC_SAP/FIFO_SAP/fifo_sap.mpc new file mode 100644 index 00000000000..1e6d04447e5 --- /dev/null +++ b/ACE/examples/IPC_SAP/FIFO_SAP/fifo_sap.mpc @@ -0,0 +1,42 @@ +// -*- MPC -*- +// $Id$ + +project(*client) : aceexe { + avoids += ace_for_tao + exename = FIFO-client + Source_Files { + FIFO-client.cpp + } +} + +project(*server) : aceexe { + avoids += ace_for_tao + exename = FIFO-server + Source_Files { + FIFO-server.cpp + } +} + +project(*Msg_Client) : aceexe { + exename = FIFO-Msg-client + Source_Files { + FIFO-Msg-client.cpp + } +} + +project(*Msg_Server) : aceexe { + exename = FIFO-Msg-server + Source_Files { + FIFO-Msg-server.cpp + } +} + +project(*test) : aceexe { + avoids += ace_for_tao + exename = FIFO-test + Source_Files { + FIFO-test.cpp + } +} + + diff --git a/ACE/examples/IPC_SAP/FILE_SAP/Makefile.am b/ACE/examples/IPC_SAP/FILE_SAP/Makefile.am new file mode 100644 index 00000000000..64d2126adcf --- /dev/null +++ b/ACE/examples/IPC_SAP/FILE_SAP/Makefile.am @@ -0,0 +1,39 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + + +## Makefile.file_sap_client.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS = client + +client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +client_SOURCES = \ + client.cpp + +client_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/IPC_SAP/FILE_SAP/client.cpp b/ACE/examples/IPC_SAP/FILE_SAP/client.cpp new file mode 100644 index 00000000000..7c2402f0b3e --- /dev/null +++ b/ACE/examples/IPC_SAP/FILE_SAP/client.cpp @@ -0,0 +1,90 @@ +// $Id$ + +#include "ace/OS_main.h" +#include "ace/FILE_Addr.h" +#include "ace/FILE_Connector.h" +#include "ace/FILE_IO.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_stdio.h" + +ACE_RCSID(FILE_SAP, client, "$Id$") + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc < 3 || argc > 3) + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s filename string\n", + argv[0]), + 1); + + ACE_TCHAR *readback = new ACE_TCHAR[ACE_OS::strlen (argv[1]) + 1]; + + ACE_FILE_Info fileinfo; + ACE_FILE_IO cli_file; + ACE_FILE_Connector con; + + if (con.connect (cli_file, + ACE_FILE_Addr (argv[1]), + 0, + ACE_Addr::sap_any, 0, + O_RDWR|O_APPEND|O_CREAT, + ACE_DEFAULT_FILE_PERMS) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n to %s", + "connect", + argv[1]), + -1); + + ssize_t len = ACE_OS::strlen (argv[2]) + 1; + + if (cli_file.send (argv[2], len) != len) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "send"), + 1); + + if (cli_file.get_info (&fileinfo) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "get_info"), + 1); + else + ACE_OS::printf ("fileinfo : mode = %o\nno of links = %lu\nsize = %lu\n", + (u_int) fileinfo.mode_ & 0777, + static_cast<u_long > (fileinfo.nlink_), + (u_long) fileinfo.size_); + + ACE_OFF_T fpos = cli_file.tell (); + + if (fpos == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "tell"), + 1); + else + ACE_OS::printf ("current filepointer is at %ld\n", + (long int) fpos); + + if (cli_file.seek (0, + SEEK_SET) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "seek"), + 1); + if (cli_file.recv (readback, len) != len) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "recv"), + 1); + + ACE_OS::printf ("read back :%s\n", + readback); + + if (cli_file.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "close"), + 1); + return 0; +} diff --git a/ACE/examples/IPC_SAP/FILE_SAP/file_sap_client.mpc b/ACE/examples/IPC_SAP/FILE_SAP/file_sap_client.mpc new file mode 100644 index 00000000000..24f9a2b3a61 --- /dev/null +++ b/ACE/examples/IPC_SAP/FILE_SAP/file_sap_client.mpc @@ -0,0 +1,11 @@ +// -*- MPC -*- +// $Id$ + +project : aceexe { + avoids += ace_for_tao + exename = client + Source_Files { + client.cpp + } +} + diff --git a/ACE/examples/IPC_SAP/FILE_SAP/testfile b/ACE/examples/IPC_SAP/FILE_SAP/testfile new file mode 100644 index 00000000000..e7cbb71a0d5 --- /dev/null +++ b/ACE/examples/IPC_SAP/FILE_SAP/testfile @@ -0,0 +1 @@ +testfile
\ No newline at end of file diff --git a/ACE/examples/IPC_SAP/Makefile.am b/ACE/examples/IPC_SAP/Makefile.am new file mode 100644 index 00000000000..31c046f885a --- /dev/null +++ b/ACE/examples/IPC_SAP/Makefile.am @@ -0,0 +1,21 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +SUBDIRS = \ + ATM_SAP \ + DEV_SAP \ + FIFO_SAP \ + FILE_SAP \ + SOCK_SAP \ + SPIPE_SAP \ + SSL_SAP \ + TLI_SAP \ + UPIPE_SAP + diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/C-inclient.cpp b/ACE/examples/IPC_SAP/SOCK_SAP/C-inclient.cpp new file mode 100644 index 00000000000..1781f6ab8b8 --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/C-inclient.cpp @@ -0,0 +1,84 @@ +// $Id$ + +#include "ace/OS_main.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_sys_socket.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_netdb.h" +#include "ace/Default_Constants.h" + +ACE_RCSID(SOCK_SAP, C_inclient, "$Id$") + +/* BSD socket client */ + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + // Initialize WinSock DLL on Win32... + ACE_OS::socket_init (ACE_WSOCK_VERSION); + + struct sockaddr_in saddr; + struct hostent *hp; + const ACE_TCHAR *host = argc > 1 ? argv[1] : ACE_DEFAULT_SERVER_HOST; + u_short port_num = + ACE_HTONS (argc > 2 ? ACE_OS::atoi (argv[2]) : ACE_DEFAULT_SERVER_PORT); + int sockbufsize = argc > 3 ? ACE_OS::atoi (argv[3]) : 0; + char buf[BUFSIZ]; + ACE_HANDLE s_handle; + int w_bytes; + int r_bytes; + int n; + + // Create a local endpoint of communication. + if ((s_handle = ACE_OS::socket (PF_INET, SOCK_STREAM, 0)) == ACE_INVALID_HANDLE) + ACE_OS::perror (ACE_TEXT("socket")), ACE_OS::exit (1); + + // If a sockbufsize was specified, set it for both send and receive. + if (sockbufsize > 0) + { + if (ACE_OS::setsockopt (s_handle, SOL_SOCKET, SO_SNDBUF, + (const char *) &sockbufsize, + sizeof (sockbufsize)) != 0) + ACE_OS::perror (ACE_TEXT("SO_SNDBUF")), ACE_OS::exit (1); + if (ACE_OS::setsockopt (s_handle, SOL_SOCKET, SO_RCVBUF, + (const char *) &sockbufsize, + sizeof (sockbufsize)) != 0) + ACE_OS::perror (ACE_TEXT("SO_RCVBUF")), ACE_OS::exit (1); + } + + // Determine IP address of the server. + if ((hp = ACE_OS::gethostbyname (ACE_TEXT_ALWAYS_CHAR(host))) == 0) + ACE_OS::perror (ACE_TEXT("gethostbyname")), ACE_OS::exit (1); + + // Set up the address information to contact the server. + ACE_OS::memset ((void *) &saddr, 0, sizeof saddr); + saddr.sin_family = AF_INET; + saddr.sin_port = port_num; + ACE_OS::memcpy (&saddr.sin_addr, hp->h_addr, hp->h_length); + + // Establish connection with remote server. + if (ACE_OS::connect (s_handle, + reinterpret_cast<sockaddr *> (&saddr), + sizeof saddr) == -1) + ACE_OS::perror (ACE_TEXT("connect")), ACE_OS::exit (1); + + // Send data to server (correctly handles "incomplete writes" due to + // flow control). + + while ((r_bytes = ACE_OS::read (ACE_STDIN, buf, sizeof buf)) > 0) + for (w_bytes = 0; w_bytes < r_bytes; w_bytes += n) + if ((n = ACE_OS::send (s_handle, buf + w_bytes, + r_bytes - w_bytes)) < 0) + ACE_OS::perror (ACE_TEXT("write")), ACE_OS::exit (1); + + if (ACE_OS::recv (s_handle, buf, 1) == 1) + ACE_OS::write (ACE_STDOUT, buf, 1); + + // Explicitly close the connection. + if (ACE_OS::closesocket (s_handle) == -1) + ACE_OS::perror (ACE_TEXT("close")), ACE_OS::exit (1); + + return 0; +} diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/C-inserver.cpp b/ACE/examples/IPC_SAP/SOCK_SAP/C-inserver.cpp new file mode 100644 index 00000000000..f42dcc82dd1 --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/C-inserver.cpp @@ -0,0 +1,116 @@ +// $Id$ + +#include "ace/OS_main.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_sys_socket.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_netdb.h" +#include "ace/OS_NS_errno.h" +#include "ace/Default_Constants.h" + +ACE_RCSID(SOCK_SAP, C_inserver, "$Id$") + +/* BSD socket server. */ + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + // Initialize WinSock DLL on Win32... + ACE_OS::socket_init (ACE_WSOCK_VERSION); + + u_short port_num = + ACE_HTONS (argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_DEFAULT_SERVER_PORT); + int sockbufsize = argc > 2 ? ACE_OS::atoi (argv[2]) : 0; + struct sockaddr_in saddr; + ACE_HANDLE s_handle, n_handle; + + /* Create a local endpoint of communication */ + if ((s_handle = ACE_OS::socket (PF_INET, SOCK_STREAM, 0)) == ACE_INVALID_HANDLE) + ACE_OS::perror (ACE_TEXT("socket")), ACE_OS::exit (1); + + // If a sockbufsize was specified, set it for both send and receive. + if (sockbufsize > 0) + { + if (ACE_OS::setsockopt (s_handle, SOL_SOCKET, SO_SNDBUF, + (const char *) &sockbufsize, + sizeof (sockbufsize)) != 0) + ACE_OS::perror (ACE_TEXT("SO_SNDBUF")), ACE_OS::exit (1); + if (ACE_OS::setsockopt (s_handle, SOL_SOCKET, SO_RCVBUF, + (const char *) &sockbufsize, + sizeof (sockbufsize)) != 0) + ACE_OS::perror (ACE_TEXT("SO_RCVBUF")), ACE_OS::exit (1); + } + + /* Set up the address information to become a server */ + ACE_OS::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 */ + if (ACE_OS::bind (s_handle, + reinterpret_cast<struct sockaddr *> (&saddr), + sizeof saddr) == -1) + ACE_OS::perror (ACE_TEXT("bind")), ACE_OS::exit (1); + + /* Make endpoint listen for service requests */ + if (ACE_OS::listen (s_handle, 5) == -1) + ACE_OS::perror (ACE_TEXT("listen")), ACE_OS::exit (1); + + /* Performs the iterative server activities */ + + for (;;) + { + char buf[BUFSIZ]; + int r_bytes; + struct sockaddr_in cli_addr; + int cli_addr_len = sizeof cli_addr; + struct hostent *hp; + + /* Create a new endpoint of communication */ + do + n_handle = + ACE_OS::accept (s_handle, + reinterpret_cast<struct sockaddr *> (&cli_addr), + &cli_addr_len); + while (n_handle == ACE_INVALID_HANDLE && errno == EINTR); + + if (n_handle == ACE_INVALID_HANDLE) + { + ACE_OS::perror (ACE_TEXT("accept")); + continue; + } + +#if !defined(_UNICOS) + int addr_len = sizeof cli_addr.sin_addr.s_addr; +#else /* ! _UNICOS */ + // sizeof on bitfield fails + int addr_len = sizeof cli_addr.sin_addr; // 32 bit biffield in UNICOS +#endif /* ! _UNICOS */ + hp = ACE_OS::gethostbyaddr ((char *) &cli_addr.sin_addr, + addr_len, AF_INET); + + if (hp != 0) + ACE_OS::printf ("client %s\n", hp->h_name), ACE_OS::fflush (stdout); + else + ACE_OS::perror (ACE_TEXT("gethostbyaddr")); + + /* Read data from client (terminate on error) */ + + while ((r_bytes = ACE_OS::recv (n_handle, buf, sizeof buf)) > 0) + if (ACE_OS::write (ACE_STDOUT, buf, r_bytes) != r_bytes) + ACE_OS::perror (ACE_TEXT("write")), ACE_OS::exit (1); + + if (ACE_OS::send (n_handle, "", 1) != 1) + ACE_OS::perror ("write"), ACE_OS::exit (1); + + /* Close the new endpoint + (listening endpoint remains open) */ + if (ACE_OS::closesocket (n_handle) == -1) + ACE_OS::perror (ACE_TEXT("close")), ACE_OS::exit (1); + ACE_OS::exit (0); + } + + ACE_NOTREACHED (return 0;) +} diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inclient.cpp b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inclient.cpp new file mode 100644 index 00000000000..96d27308c87 --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inclient.cpp @@ -0,0 +1,427 @@ +// $Id$ + +// This tests the features of the <ACE_SOCK_Connector> and +// <ACE_SOCK_Stream> classes. In addition, it can be used to test the +// oneway and twoway latency and throughput at the socket-level. This +// is useful as a baseline to compare against ORB-level performance +// for the same types of data. + +#include "CPP-inclient.h" + +#include "ace/SOCK_Connector.h" +#include "ace/INET_Addr.h" +#include "ace/Thread_Manager.h" +#include "ace/Singleton.h" +#include "ace/Get_Opt.h" +#include "ace/High_Res_Timer.h" +#include "ace/Basic_Types.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_main.h" + +ACE_RCSID(SOCK_SAP, CPP_inclient, "$Id$") + +Options::Options (void) + : host_ (ACE_DEFAULT_SERVER_HOST), + port_ (ACE_DEFAULT_SERVER_PORT), + sleep_time_ (0, 0), // By default, don't sleep between calls. + threads_ (10), + quit_string_ (ACE_TEXT("q")), + message_len_ (0), + message_buf_ (0), + io_source_ (ACE_INVALID_HANDLE), // Defaults to using the generator. + iterations_ (10000), + oneway_ (1) // Make oneway calls the default. +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + , barrier_ (0) +#endif /* ACE_MT_SAFE */ +{ +} + +Options::~Options (void) +{ + ACE_MT (delete this->barrier_); + delete [] this->message_buf_; +} + +// Options Singleton. +typedef ACE_Singleton<Options, ACE_SYNCH_RECURSIVE_MUTEX> OPTIONS; + +int +Options::init (void) +{ + + ACE_DEBUG((LM_DEBUG,"Options::init, len = %d\n",this->message_len_)); + + // Check for default case. + if (this->message_len_ == 0) + this->message_len_ = ACE_OS::strlen ("TAO"); + ACE_DEBUG((LM_DEBUG,"Options::init, len = %d\n",this->message_len_)); + + this->message_len_ += sizeof (ACE_UINT32); + ACE_DEBUG((LM_DEBUG,"Options::init, len = %d\n",this->message_len_)); + + ACE_NEW_RETURN (this->message_buf_, + char[this->message_len_], + -1); + + // Copy the length into the beginning of the message. + ACE_UINT32 length = ACE_NTOHL (this->message_len_); + ACE_OS::memcpy ((void *) this->message_buf_, + (void *) &length, + sizeof length); + + ACE_OS::memset ((void *) (this->message_buf_ + sizeof (ACE_UINT32)), + 'a', + this->message_len_ - sizeof (ACE_UINT32)); + + // Allocate the barrier with the correct count. + ACE_MT (ACE_NEW_RETURN (this->barrier_, + ACE_Barrier (this->threads_), + -1)); + return 0; +} + +size_t +Options::message_len (void) const +{ + return this->message_len_; +} + +const void * +Options::message_buf (void) const +{ + return this->message_buf_; +} + +ssize_t +Options::read (void *buf, size_t len, size_t &iteration) +{ + ACE_UNUSED_ARG (len); + + if (this->io_source_ == ACE_STDIN) + return ACE_OS::read (ACE_STDIN, buf, len); + else if (iteration >= this->iterations_) + return 0; + else + { + ACE_OS::memcpy (buf, + this->message_buf (), + len); + iteration++; + return len; + } +} + +int +Options::parse_args (int argc, ACE_TCHAR *argv[]) +{ + //FUZZ: disable check_for_lack_ACE_OS + ACE_Get_Opt getopt (argc, argv, ACE_TEXT("2h:i:m:p:q:st:T:"), 1); + + for (int c; (c = getopt ()) != -1; ) + //FUZZ: enable check_for_lack_ACE_OS + switch (c) + { + case '2': // Disable the oneway client. + this->oneway_ = 0; + break; + case 'h': + this->host_ = getopt.opt_arg (); + break; + case 'i': + this->iterations_ = ACE_OS::atoi (getopt.opt_arg ()); + break; + case 'm': + this->message_len_ = ACE_OS::atoi (getopt.opt_arg ()); + break; + case 'p': + this->port_ = ACE_OS::atoi (getopt.opt_arg ()); + break; + case 'q': + this->quit_string_ = getopt.opt_arg (); + break; + case 's': + this->io_source_ = ACE_STDIN; + break; + case 't': + this->threads_ = (size_t) ACE_OS::atoi (getopt.opt_arg ()); + break; + case 'T': + this->sleep_time_.set (0, ACE_OS::atoi (getopt.opt_arg ())); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) usage: %n [-2] [-h <host>] [-i iterations] [-m message-size] [-p <port>] [-q <quit string>] [-s] [-t <threads>] [-T <sleep_time>]\n"), + -1); + } + + return this->init (); +} + +u_short +Options::port (void) const +{ + return this->port_; +} + +const ACE_TCHAR * +Options::host (void) const +{ + return this->host_; +} + +const ACE_TCHAR * +Options::quit_string (void) const +{ + return this->quit_string_; +} + +size_t +Options::threads (void) const +{ + return this->threads_; +} + +const ACE_Time_Value & +Options::sleep_time (void) const +{ + return this->sleep_time_; +} + +char * +Options::shared_client_test (u_short port, + ACE_SOCK_Stream &cli_stream) +{ + ACE_INET_Addr remote_addr (port, this->host_); + + ACE_SOCK_Connector con; + + if (con.connect (cli_stream, + remote_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) %p\n", + "connection failed"), + 0); + else + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) connected to %s at port %d\n", + remote_addr.get_host_name (), + remote_addr.get_port_number ())); + + ACE_INT32 len = ACE_HTONL (this->message_len ()); + + // Allocate the transmit buffer. + char *buf; + ACE_DEBUG((LM_DEBUG,"(%P|%t) allocating buffer, len = %d msglen = %d\n", + len, message_len_)); + + ACE_NEW_RETURN (buf, + char[this->message_len()], + 0); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) waiting...\n")); + + // Wait for all other threads to finish initialization. + ACE_MT (this->barrier_->wait ()); + return buf; +} +// Static function entry point to the oneway client service. + +void * +Options::oneway_client_test (void *) +{ + Options *options = OPTIONS::instance (); + ACE_SOCK_Stream cli_stream; + + ACE_DEBUG((LM_DEBUG,"options = %d, len = %d\n",options,options->message_len())); + + // Add 1 to the port to trigger the oneway test! + char *request = options->shared_client_test (options->port () + 1, + cli_stream); + if (request == 0) + return 0; + + // This variable is allocated off the stack to obviate the need for + // locking. + size_t iteration = 0; + + // Keep track of return value. + intptr_t result = 0; + ACE_INT32 len = options->message_len (); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) starting oneway transmission\n")); + + // Perform oneway transmission of data to server (correctly handles + // "incomplete writes"). + + for (ssize_t r_bytes; + (r_bytes = options->read (request, len, iteration)) > 0; + // Transmit at the proper rate. + ACE_OS::sleep (options->sleep_time ())) + if (ACE_OS::memcmp (request, + options->quit_string (), + ACE_OS::strlen (options->quit_string ())) == 0) + break; + else if (cli_stream.send_n (request, r_bytes) == -1) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) %p\n", + "send_n")); + result = -1; + break; + } + + // Close the connection. + cli_stream.close (); + + delete [] request; + return reinterpret_cast<void *> (result); +} + +// Static function entry point to the twoway client service. + +void * +Options::twoway_client_test (void *) +{ + Options *options = OPTIONS::instance (); + + ACE_SOCK_Stream cli_stream; + + char *request = options->shared_client_test (options->port (), + cli_stream); + if (request == 0) + return 0; + + // This variable is allocated off the stack to obviate the need for + // locking. + size_t iteration = 0; + + // Keep track of return value. + intptr_t result = 0; + + // Timer business. + ACE_High_Res_Timer timer; + + ACE_INT32 len = options->message_len (); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) starting twoway transmission\n")); + + // Perform twoway transmission of data to server (correctly handles + // "incomplete writes"). + + for (ssize_t r_bytes; + (r_bytes = options->read (request, len, iteration)) > 0; + // Transmit at the proper rate. + ACE_OS::sleep (options->sleep_time ())) + if (ACE_OS::memcmp (request, + options->quit_string (), + ACE_OS::strlen (options->quit_string ())) == 0) + break; + + // Transmit <request> to the server. + else + { + // Note that we use the incremental feature of the + // <ACE_High_Res_Timer> so that we don't get "charged" for the + // <ACE_OS::sleep> used to control the rate at which requests + // are sent. + timer.start_incr (); + + if (cli_stream.send_n (request, r_bytes) == -1) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) %p\n", + "send_n")); + result = -1; + break; + } + // Receive the reply from the server. Normally, it just sends + // back 24 bytes, which is typical for an IIOP reply. + else if (cli_stream.recv (request, r_bytes) <= 0) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) %p\n", + "recv")); + result = -1; + break; + } + + timer.stop_incr (); + } + + ACE_Time_Value tv; + + timer.elapsed_time_incr (tv); + double real_time = (long) tv.sec () * ACE_ONE_SECOND_IN_USECS + tv.usec (); + double messages_per_sec = iteration * double (ACE_ONE_SECOND_IN_USECS) / real_time; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) messages = %d\n(%t) usec-per-message = %f\n(%t) messages-per-second = %0.00f\n"), + iteration, + real_time / double (iteration), + messages_per_sec < 0 ? 0 : messages_per_sec)); + + // Close the connection. + cli_stream.close (); + + delete [] request; + return reinterpret_cast<void *> (result); +} + +ACE_THR_FUNC +Options::thr_func (void) +{ + ACE_DEBUG((LM_DEBUG,"(%P|%t) in thread func, mesg len = %d\n",this->message_len())); + if (this->oneway_ == 0) + return ACE_THR_FUNC (&Options::twoway_client_test); + else + return ACE_THR_FUNC (&Options::oneway_client_test); +} + +static int +run_client (void) +{ + // Raise the socket handle limit to the maximum. + ACE::set_handle_limit (); + +#if defined (ACE_HAS_THREADS) + ACE_DEBUG((LM_DEBUG,"(%P|%t) spawning client test thread options = %d\n", + OPTIONS::instance())); + + if (ACE_Thread_Manager::instance ()->spawn_n (OPTIONS::instance ()->threads (), + OPTIONS::instance ()->thr_func ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) %p\n", + "spawn_n"), + 1); + else + ACE_Thread_Manager::instance ()->wait (); +#else + *(OPTIONS::instance ()->thr_func) (); +#endif /* ACE_HAS_THREADS */ + return 0; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + // Initialize the logger. + ACE_LOG_MSG->open (argv[0]); + + if (OPTIONS::instance ()->parse_args (argc, argv) == -1) + return -1; + + // Run the client + run_client (); + + return 0; +} + +#if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION) +template ACE_Singleton<Options, ACE_SYNCH_RECURSIVE_MUTEX> * + ACE_Singleton<Options, ACE_SYNCH_RECURSIVE_MUTEX>::singleton_; +#endif /* ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION */ diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inclient.h b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inclient.h new file mode 100644 index 00000000000..7486c70b749 --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inclient.h @@ -0,0 +1,108 @@ +// $Id$ + +// This file defines the Options class for CPP-inclient. IBM C++ compiler'd +// template auto-instantiator needs this in a separate file. + +#ifndef __CPP_INCLIENT_H +#define __CPP_INCLIENT_H + +#include "ace/SOCK_Stream.h" +#include "ace/Barrier.h" +#include "ace/Time_Value.h" + +class Options + // = TITLE + // Define the options for this test. +{ +public: + Options (void); + // Constructor. + + ~Options (void); + // Destructor. + + int parse_args (int argc, ACE_TCHAR *argv[]); + // Parse the command-line arguments. + + const ACE_Time_Value &sleep_time (void) const; + // Return the amount of time to sleep in order to implement the + // proper transmission rates. + + u_short port (void) const; + // Port of the server. + + const ACE_TCHAR *host (void) const; + // Host of the server. + + size_t threads (void) const; + // Number of threads. + + const ACE_TCHAR *quit_string (void) const; + // String that shuts down the client/server. + + ssize_t read (void *buf, size_t len, size_t &iterations); + // Read from the appropriate location. + + size_t message_len (void) const; + // Returns the length of the message to send. + + const void *message_buf (void) const; + // Returns a pointer to the message. + + ACE_THR_FUNC thr_func (void); + // Returns a pointer to the entry point into the thread that runs + // the client test function. + +private: + int init (void); + // Initialize the message we're sending to the user and set up the + // barrier. + + char *shared_client_test (u_short port, + ACE_SOCK_Stream &cli_stream); + // Performs the shared behavior of the oneway and twoway client + // tests. + + static void *twoway_client_test (void *); + // Performs the twoway test. + + static void *oneway_client_test (void *); + // Performs the oneway test. + + const ACE_TCHAR *host_; + // Host of the server. + + u_short port_; + // Port of the server. + + ACE_Time_Value sleep_time_; + // Sleep_Time value. + + size_t threads_; + // Number of threads. + + const ACE_TCHAR *quit_string_; + // String that shuts down the client/server. + + size_t message_len_; + // Size of the message we send to the server. + + char *message_buf_; + // Pointer to the message we send to the server. + + ACE_HANDLE io_source_; + // Are we reading I/O from ACE_STDIN or from our generator? + + size_t iterations_; + // Number of iterations. + + char oneway_; + // Are we running oneway or twoway? + + // Please leave the ; inside the parenthesis to avoid Green Hills + // (and probably other) compiler warning about extra ;. + ACE_MT (ACE_Barrier *barrier_;) + // Barrier used to synchronize the start of all the threads. +}; + +#endif /* __CPP_INCLIENT_H */ diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inserver-fancy.cpp b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inserver-fancy.cpp new file mode 100644 index 00000000000..fe0d49d4ce4 --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inserver-fancy.cpp @@ -0,0 +1,586 @@ + // $Id$ + +// This example tests the features of the <ACE_SOCK_Acceptor>, +// <ACE_SOCK_Stream>, and <ACE_Svc_Handler> classes. If the platform +// supports threads it uses a thread-per-connection concurrency model. +// Otherwise, it uses a single-threaded iterative server model. + +#include "ace/OS_main.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/Svc_Handler.h" +#include "ace/Singleton.h" +#include "ace/Profile_Timer.h" +#include "ace/Get_Opt.h" +#include "ace/OS_NS_sys_select.h" + +#include "CPP-inserver-fancy.h" + +ACE_RCSID(SOCK_SAP, CPP_inserver_fancy, "$Id$") + +// Forward declaration. +class Handler; + +class Handler_Factory +{ + // = TITLE + // Creates the oneway or twoway handlers. +public: + Handler_Factory (void); + // Constructor. + + ~Handler_Factory (void); + // Destructor. + + int handle_events (void); + // Run the main event loop. + +private: + int init_acceptors (void); + // Initialize the acceptors. + + int create_handler (ACE_SOCK_Acceptor &acceptor, + Handler *(*handler_factory) (ACE_HANDLE), + const char *handler_type); + // Factory that creates the right kind of <Handler>. + + // = Factory functions. + static Handler *make_twoway_handler (ACE_HANDLE); + // Create a twoway handler. + + static Handler *make_oneway_handler (ACE_HANDLE); + // Create a oneway handler. + + ACE_SOCK_Acceptor twoway_acceptor_; + // Twoway acceptor factory. + + ACE_SOCK_Acceptor oneway_acceptor_; + // Oneway acceptor factory. +}; + +class Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> +{ + // = TITLE + // Base class for the oneway and twoway handlers. + + friend class Handler_Factory; + // The factory has special permission. (to access svc ()). + +public: + //FUZZ: disable check_for_lack_ACE_OS + virtual int open (void * = 0); + // Generic initialization method. + + virtual int close (u_long); + // Close down and delete this. + //FUZZ: enable check_for_lack_ACE_OS + +protected: + Handler (ACE_HANDLE handle); + // Constructor. + + int parse_header_and_allocate_buffer (char *&buf, + ACE_INT32 *len); + // Implement the generic code that's called from any of the subclass + // <run> methods to get the header and the buffer to read the data. + // This method factors out common code. + + virtual int run (void) = 0; + // Hook method called by the <svc> template method to do the actual + // protocol. Must be overridden by the subclass. + + virtual int svc (void); + // Template method entry point into the handler task. + + virtual void print_results (void); + // Print the results. + + size_t total_bytes_; + // Total number of bytes received. + + size_t message_count_; + // Number of messages received. + + ACE_Profile_Timer timer_; + // Keeps track of how much time we're using. +}; + +class Twoway_Handler : public Handler +{ + // = TITLE + // Performs the twoway protocol. +public: + Twoway_Handler (ACE_HANDLE handle); + // Constructor. + +private: + virtual int run (void); + // Template Method hook called by <svc>. +}; + +class Oneway_Handler : public Handler +{ + // = TITLE +public: + Oneway_Handler (ACE_HANDLE handle); + // Constructor. + +private: + virtual int run (void); + // Template Method hook called by <svc>. + + virtual void print_results (void); + // Print the results. +}; + +u_short +Options::port (void) const +{ + return this->port_; +} + +int +Options::verbose (void) const +{ + return this->verbose_; +} + +int +Options::reply_message_len (void) const +{ + return this->reply_message_len_; +} + +Options::~Options (void) +{ +} + +Options::Options (void) + : verbose_ (0), + port_ (ACE_DEFAULT_SERVER_PORT), + reply_message_len_ (24) // Default to the approximate size of an + // GIOP reply message. +{ +} + +int +Options::parse_args (int argc, ACE_TCHAR *argv[]) +{ + //FUZZ: disable check_for_lack_ACE_OS + ACE_Get_Opt getopt (argc, argv, ACE_TEXT("p:r:v"), 1); + + for (int c; (c = getopt ()) != -1; ) + //FUZZ: enable check_for_lack_ACE_OS + switch (c) + { + case 'p': + this->port_ = ACE_OS::atoi (getopt.opt_arg ()); + break; + case 'r': + this->reply_message_len_ = ACE_OS::atoi (getopt.opt_arg ()); + break; + case 'v': + this->verbose_ = 1; + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) usage: %n [-p <port>] [-v]"), + -1); + } + + return 0; +} + +// Options Singleton. +typedef ACE_Singleton<Options, ACE_SYNCH_RECURSIVE_MUTEX> OPTIONS; + +Handler::Handler (ACE_HANDLE handle) + : total_bytes_ (0), + message_count_ (0) +{ + this->peer ().set_handle (handle); +} + +int +Handler::open (void *) +{ + ACE_INET_Addr cli_addr; + + // Make sure we're not in non-blocking mode. + if (this->peer ().disable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "disable"), + 0); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) client %s connected from %d on handle %d\n", + cli_addr.get_host_name (), + cli_addr.get_port_number (), + this->peer ().get_handle ())); + return 0; +} + +int +Handler::close (u_long) +{ + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) closing down %x\n", + this)); + delete this; + return 0; +} + +int +Handler::svc (void) +{ + // Timer logic. + this->timer_.start (); + + // Invoke the hook method to run the specific test. + int result = this->run (); + + this->timer_.stop (); + + this->print_results (); + + return result; +} + +int +Handler::parse_header_and_allocate_buffer (char *&request, + ACE_INT32 *len) +{ + ssize_t result = this->peer ().recv_n ((void *) len, + sizeof (ACE_INT32)); + if (result == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) connected closed\n")); + return -1; + } + else if (result == -1 || result != sizeof (ACE_INT32)) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) %p\n", + "recv_n failed"), + -1); + else + { + *len = ntohl (*len); + ACE_NEW_RETURN (request, + char[*len], + -1); + } + + return 0; +} + +void +Handler::print_results (void) +{ +} + +Twoway_Handler::Twoway_Handler (ACE_HANDLE handle) + : Handler (handle) +{ +} + +// Function entry point into the twoway server task. + +int +Twoway_Handler::run (void) +{ + // Read data from client (terminate on error). + + char *request = 0; + + for (;;) + { + ACE_INT32 len = 0; + + if (parse_header_and_allocate_buffer (request, + &len) == -1) + return -1; + + // Subtract off the sizeof the length prefix. + ssize_t r_bytes = this->peer ().recv_n (request, + len - sizeof (ACE_UINT32)); + + if (r_bytes == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "recv")); + break; + } + else if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reached end of input, connection closed by client\n")); + break; + } + else if (OPTIONS::instance ()->verbose () + && ACE::write_n (ACE_STDOUT, + request, + r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, + "%p\n", + "ACE::write_n")); + else + { + ssize_t s_bytes = (ssize_t) OPTIONS::instance ()->reply_message_len (); + + // Don't try to send more than is in the request buffer! + if (s_bytes > r_bytes) + s_bytes = r_bytes; + + if (this->peer ().send_n (request, + s_bytes) != s_bytes) + ACE_ERROR ((LM_ERROR, + "%p\n", + "send_n")); + } + this->total_bytes_ += size_t (r_bytes); + this->message_count_++; + + delete [] request; + request = 0; + } + + delete [] request; + return 0; +} + +Oneway_Handler::Oneway_Handler (ACE_HANDLE handle) + : Handler (handle) +{ +} + +void +Oneway_Handler::print_results (void) +{ + ACE_Profile_Timer::ACE_Elapsed_Time et; + this->timer_.elapsed_time (et); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\t\treal time = %f secs \n\t\tuser time = %f secs \n\t\tsystem time = %f secs\n"), + et.real_time, + et.user_time, + et.system_time)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\t\tmessages = %d\n\t\ttotal bytes = %d\n\t\tmbits/sec = %f\n\t\tusec-per-message = %f\n"), + this->message_count_, + this->total_bytes_, + (((double) this->total_bytes_ * 8) / et.real_time) / (double) (1024 * 1024), + ((et.user_time + et.system_time) / (double) this->message_count_) * ACE_ONE_SECOND_IN_USECS)); +} + +// Function entry point into the oneway server task. + +int +Oneway_Handler::run (void) +{ + // Read data from client (terminate on error). + + char *request = 0; + + for (;;) + { + ACE_INT32 len = 0; + + if (parse_header_and_allocate_buffer (request, + &len) == -1) + return -1; + + // Subtract off the sizeof the length prefix. + ssize_t r_bytes = this->peer ().recv_n (request, + len - sizeof (ACE_UINT32)); + + if (r_bytes == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "recv")); + break; + } + else if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reached end of input, connection closed by client\n")); + break; + } + else if (OPTIONS::instance ()->verbose () + && ACE::write_n (ACE_STDOUT, + request, + r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, + "%p\n", + "ACE::write_n")); + + this->total_bytes_ += size_t (r_bytes); + this->message_count_++; + delete [] request; + request = 0; + } + + delete [] request; + return 0; +} + +// Create a twoway handler. + +Handler * +Handler_Factory::make_twoway_handler (ACE_HANDLE handle) +{ + return new Twoway_Handler (handle); +} + +// Create a oneway handler. + +Handler * +Handler_Factory::make_oneway_handler (ACE_HANDLE handle) +{ + return new Oneway_Handler (handle); +} + +int +Handler_Factory::init_acceptors (void) +{ + // Create the oneway and twoway server addresses. + ACE_INET_Addr twoway_server_addr (OPTIONS::instance ()->port ()); + ACE_INET_Addr oneway_server_addr (OPTIONS::instance ()->port () + 1); + + // Create acceptors, reuse the address. + if (this->twoway_acceptor_.open (twoway_server_addr, 1) == -1 + || this->oneway_acceptor_.open (oneway_server_addr, 1) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "open"), + -1); + else if (this->twoway_acceptor_.get_local_addr (twoway_server_addr) == -1 + || this->oneway_acceptor_.get_local_addr (oneway_server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "get_local_addr"), + -1); + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) starting twoway server at port %d and oneway server at port %d\n", + twoway_server_addr.get_port_number (), + oneway_server_addr.get_port_number ())); + return 0; +} + +int +Handler_Factory::create_handler (ACE_SOCK_Acceptor &acceptor, + Handler * (*handler_factory) (ACE_HANDLE), + const char *handler_type) +{ + ACE_SOCK_Stream new_stream; + + if (acceptor.accept (new_stream) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "accept"), + -1); + + Handler *handler; + + ACE_ALLOCATOR_RETURN (handler, + (*handler_factory) (new_stream.get_handle ()), + -1); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) spawning %s handler\n", + handler_type)); + + if (handler->open () == -1) + return -1; + +#if defined (ACE_MT_SAFE) + // Spawn a new thread and run the new connection in that thread of + // control using the <server> function as the entry point. + return handler->activate (); +#else + handler->svc (); + handler->close (0); + return 0; +#endif /* ACE_HAS_THREADS */ +} + +Handler_Factory::Handler_Factory (void) +{ +} + +Handler_Factory::~Handler_Factory (void) +{ + this->twoway_acceptor_.close (); + this->oneway_acceptor_.close (); +} + +// Run the main event loop. + +int +Handler_Factory::handle_events (void) +{ + if (this->init_acceptors () == -1) + return -1; + + fd_set handles; + + FD_ZERO (&handles); + FD_SET ((ACE_SOCKET) this->twoway_acceptor_.get_handle (), + &handles); + FD_SET ((ACE_SOCKET) this->oneway_acceptor_.get_handle (), + &handles); + + // Performs the iterative server activities. + + for (;;) + { + ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT); + fd_set temp = handles; + + int result = ACE_OS::select (int (this->oneway_acceptor_.get_handle ()) + 1, + (fd_set *) &temp, + 0, + 0, + timeout); + if (result == -1) + ACE_ERROR ((LM_ERROR, + "(%P|%t) %p\n", + "select")); + else if (result == 0 && OPTIONS::instance ()->verbose ()) + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) select timed out\n")); + else + { + if (FD_ISSET ((ACE_SOCKET) this->twoway_acceptor_.get_handle (), + &temp)) + this->create_handler (this->twoway_acceptor_, + &Handler_Factory::make_twoway_handler, + "twoway"); + if (FD_ISSET ((ACE_SOCKET) this->oneway_acceptor_.get_handle (), + &temp)) + this->create_handler (this->oneway_acceptor_, + &Handler_Factory::make_oneway_handler, + "oneway"); + } + } + + ACE_NOTREACHED (return 0;) +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + OPTIONS::instance ()->parse_args (argc, argv); + + Handler_Factory server; + + return server.handle_events (); +} + +#if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION) +template ACE_Singleton<Options, ACE_SYNCH_RECURSIVE_MUTEX> * + ACE_Singleton<Options, ACE_SYNCH_RECURSIVE_MUTEX>::singleton_; +#endif /* ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION */ diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inserver-fancy.h b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inserver-fancy.h new file mode 100644 index 00000000000..9901bcc0b20 --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inserver-fancy.h @@ -0,0 +1,43 @@ +// $Id$ + +// This file defines the Options class for CPP-inserver-fancy. +// IBM C++ compiler'd template auto-instantiator needs this in a separate file. + +#ifndef __CPP_INSERVER_FANCY_H +#define __CPP_INSERVER_FANCY_H + +class Options + // = TITLE + // Define the options for this test. +{ +public: + Options (void); + // Constructor. + + ~Options (void); + // Destructor. + + int parse_args (int argc, ACE_TCHAR *argv[]); + // Parse the command-line arguments. + + int verbose (void) const; + // Are we running in verbose mode? + + u_short port (void) const; + // Port number that we are listening at. + + int reply_message_len (void) const; + // Size of the reply message. + +private: + int verbose_; + // Are we running in verbose mode? + + u_short port_; + // Port number we listen at. + + size_t reply_message_len_; + // Size of the reply message. +}; + +#endif /* __CPP_INSERVER_FANCY_H */ diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inserver-poll.cpp b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inserver-poll.cpp new file mode 100644 index 00000000000..a281d2e380d --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inserver-poll.cpp @@ -0,0 +1,207 @@ +// $Id$ + +// IPC_SAP/poll server, which illustrates how to integrate the ACE +// socket wrappers with the SVR4 <poll> system call to create a +// single-threaded concurrent server. This server program can be +// driven by the oneway test mode of CPP-inclient.cpp. + +#include "ace/OS_main.h" +#include "ace/SOCK_Acceptor.h" +#include "ace/SOCK_Stream.h" +#include "ace/INET_Addr.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_poll.h" +#include "ace/OS_NS_stdio.h" + +ACE_RCSID(SOCK_SAP, CPP_inserver_poll, "$Id$") + +#if defined (ACE_HAS_POLL) + +// Should we be verbose? +static int verbose = 0; + +// Max number of open handles. +static const int MAX_HANDLES = 200; + +struct Buffer_Info +{ + void *buf_; + // Pointer to the buffer. + + size_t len_; + // Length of the buffer. +}; + +// Array of <pollfd>'s. +static struct pollfd poll_array[MAX_HANDLES]; + +// Array of <Buffer_Info>. +static Buffer_Info buffer_array[MAX_HANDLES]; + +static void +init_poll_array (void) +{ + int i; + + for (i = 0; i < MAX_HANDLES; i++) + { + poll_array[i].fd = ACE_INVALID_HANDLE; + poll_array[i].events = POLLIN; + } +} + +static int +init_buffer (size_t index) +{ + ACE_INT32 len; + + if (ACE::recv_n (poll_array[index].fd, + (void *) &len, + sizeof (ACE_INT32)) != sizeof (ACE_INT32)) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) %p\n", + "recv_n failed"), + -1); + else + { + len = ntohl (len); + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reading messages of size %d from handle %d\n", + len, + poll_array[index].fd)); + + ACE_ALLOCATOR_RETURN (buffer_array[index].buf_, + ACE_OS::malloc (len), + -1); + buffer_array[index].len_ = len; + } + return 0; +} + +static void +handle_data (size_t &n_handles) +{ + // Handle pending logging messages first (s_handle + 1 is guaranteed + // to be lowest client descriptor). + + for (size_t index = 1; index < n_handles; index++) + { + if (ACE_BIT_ENABLED (poll_array[index].revents, POLLIN)) + { + // First time in, we need to initialize the buffer. + if (buffer_array[index].buf_ == 0 + && init_buffer (index) == -1) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) %p\n", + "init_buffer")); + continue; + } + + // Read data from client (terminate on error). + + ssize_t n = ACE::recv (poll_array[index].fd, + buffer_array[index].buf_, + buffer_array[index].len_); + // <recv> will not block in this case! + + if (n == -1) + ACE_ERROR ((LM_ERROR, + "%p\n", + "read failed")); + else if (n == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) closing oneway server at handle %d\n", + poll_array[index].fd)); + + // Handle client connection shutdown. + ACE_OS::close (poll_array[index].fd); + poll_array[index].fd = poll_array[--n_handles].fd; + + ACE_OS::free ((void *) buffer_array[index].buf_); + buffer_array[index].buf_ = 0; + buffer_array[index].len_ = 0; + } + else if (verbose) + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) %*s", + n, + buffer_array[index].buf_)); + } + } +} + +static void +handle_connections (ACE_SOCK_Acceptor &peer_acceptor, + size_t &n_handles) +{ + if (ACE_BIT_ENABLED (poll_array[0].revents, POLLIN)) + { + ACE_SOCK_Stream new_stream; + + ACE_INET_Addr client; + ACE_Time_Value nonblock (0, 0); + + // Handle all pending connection requests (note use of "polling" + // feature that doesn't block). + + while (ACE_OS::poll (poll_array, 1, nonblock) > 0) + if (peer_acceptor.accept (new_stream, &client) == -1) + ACE_OS::perror ("accept"); + else + { + const char *s = client.get_host_name (); + + ACE_ASSERT (s != 0); + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) client %s\n", + s)); + poll_array[n_handles++].fd = new_stream.get_handle (); + } + } +} + +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + u_short port = ACE_DEFAULT_SERVER_PORT + 1; + + // Create a server end-point. + ACE_INET_Addr addr (port); + ACE_SOCK_Acceptor peer_acceptor (addr); + + ACE_HANDLE s_handle = peer_acceptor.get_handle (); + + init_poll_array (); + + poll_array[0].fd = s_handle; + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) starting oneway server at port %d\n", + port)); + + for (size_t n_handles = 1;;) + { + ACE_ENDLESS_LOOP + + // Wait for client I/O events (handle interrupts). + while (ACE_OS::poll (poll_array, n_handles) == -1 + && errno == EINTR) + continue; + + handle_data (n_handles); + handle_connections (peer_acceptor, n_handles); + } + + /* NOTREACHED */ + return 0; +} +#else +#include <stdio.h> +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::fprintf (stderr, "This feature is not supported\n"); + return 0; +} +#endif /* ACE_HAS_POLL */ diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inserver.cpp b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inserver.cpp new file mode 100644 index 00000000000..b39d33940fa --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-inserver.cpp @@ -0,0 +1,392 @@ +// $Id$ + +// This example tests the features of the <ACE_SOCK_Acceptor>, +// <ACE_SOCK_Stream>, and <ACE_Svc_Handler> classes. If the platform +// supports threads it uses a thread-per-connection concurrency model. +// Otherwise, it uses a single-threaded iterative server model. + +#include "ace/SOCK_Acceptor.h" +#include "ace/Thread_Manager.h" +#include "ace/Handle_Set.h" +#include "ace/Profile_Timer.h" +#include "ace/Basic_Types.h" +#include "ace/OS_NS_sys_select.h" +#include "ace/OS_main.h" + +ACE_RCSID(SOCK_SAP, CPP_inserver, "$Id$") + +// Are we running verbosely? +static int verbose = 0; + +static void +run_server (ACE_THR_FUNC server, + ACE_HANDLE handle) +{ +#if defined (ACE_HAS_THREADS) + // Spawn a new thread and run the new connection in that thread of + // control using the <server> function as the entry point. + if (ACE_Thread_Manager::instance ()->spawn (server, + reinterpret_cast<void *> (handle), + THR_DETACHED) == -1) + ACE_ERROR ((LM_ERROR, + "(%P|%t) %p\n", + "spawn")); +#else + (*server) (reinterpret_cast<void *> (handle)); +#endif /* ACE_HAS_THREADS */ +} + +// Function entry point into the twoway server task. + +static ACE_THR_FUNC_RETURN +twoway_server (void *arg) +{ + ACE_INET_Addr cli_addr; + ACE_SOCK_Stream new_stream; + ACE_HANDLE handle = (ACE_HANDLE) (intptr_t) arg; + + new_stream.set_handle (handle); + + // Make sure we're not in non-blocking mode. + if (new_stream.disable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "disable"), + 0); + else if (new_stream.get_remote_addr (cli_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "get_remote_addr"), + 0); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) client %s connected from %d\n", + cli_addr.get_host_name (), + cli_addr.get_port_number ())); + + size_t total_bytes = 0; + size_t message_count = 0; + + char *request = 0; + + // Read data from client (terminate on error). + + for (;;) + { + ACE_INT32 len; + + ssize_t r_bytes = new_stream.recv_n ((void *) &len, + sizeof (ACE_INT32)); + if (r_bytes == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "recv")); + break; + } + else if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reached end of input, connection closed by client\n")); + break; + } + else if (r_bytes != sizeof (ACE_INT32)) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) %p\n", + "recv_n failed")); + break; + } + else + { + len = ACE_NTOHL (len); + ACE_NEW_RETURN (request, + char [len], + 0); + } + + // Subtract off the sizeof the length prefix. + r_bytes = new_stream.recv_n (request, + len - sizeof (ACE_UINT32)); + if (r_bytes == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "recv")); + break; + } + else if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reached end of input, connection closed by client\n")); + break; + } + else if (verbose + && ACE::write_n (ACE_STDOUT, + request, + r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, + "%p\n", + "ACE::write_n")); + else if (new_stream.send_n (request, + r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, + "%p\n", + "send_n")); + + total_bytes += size_t (r_bytes); + message_count++; + + delete [] request; + request = 0; + } + + // Close new endpoint (listening endpoint stays open). + new_stream.close (); + + delete [] request; + return 0; +} + +// Function entry point into the oneway server task. + +static ACE_THR_FUNC_RETURN +oneway_server (void *arg) +{ + ACE_INET_Addr cli_addr; + ACE_SOCK_Stream new_stream; + ACE_HANDLE handle = (ACE_HANDLE) (intptr_t) arg; + + new_stream.set_handle (handle); + + // Make sure we're not in non-blocking mode. + if (new_stream.disable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "disable"), + 0); + else if (new_stream.get_remote_addr (cli_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "get_remote_addr"), + 0); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) client %s connected from %d\n", + cli_addr.get_host_name (), + cli_addr.get_port_number ())); + + // Timer business + ACE_Profile_Timer timer; + timer.start (); + + size_t total_bytes = 0; + size_t message_count = 0; + + char *request = 0; + + // Read data from client (terminate on error). + + for (;;) + { + ACE_INT32 len; + + ssize_t r_bytes = new_stream.recv_n ((void *) &len, + sizeof (ACE_INT32)); + if (r_bytes == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "recv")); + break; + } + else if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reached end of input, connection closed by client\n")); + break; + } + else if (r_bytes != sizeof (ACE_INT32)) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) %p\n", + "recv_n failed")); + break; + } + else + { + len = ACE_NTOHL (len); + ACE_NEW_RETURN (request, + char [len], + 0); + } + + // Subtract off the sizeof the length prefix. + r_bytes = new_stream.recv_n (request, + len - sizeof (ACE_UINT32)); + + if (r_bytes == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "recv")); + break; + } + else if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reached end of input, connection closed by client\n")); + break; + } + else if (verbose + && ACE::write_n (ACE_STDOUT, request, r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, + "%p\n", + "ACE::write_n")); + + total_bytes += size_t (r_bytes); + message_count++; + + delete [] request; + request = 0; + } + + timer.stop (); + + ACE_Profile_Timer::ACE_Elapsed_Time et; + timer.elapsed_time (et); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\t\treal time = %f secs \n\t\tuser time = %f secs \n\t\tsystem time = %f secs\n"), + et.real_time, + et.user_time, + et.system_time)); + + double messages_per_sec = double (message_count) / et.real_time; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\t\tmessages = %d\n\t\ttotal bytes = %d\n\t\tmbits/sec = %f\n\t\tusec-per-message = %f\n\t\tmessages-per-second = %0.00f\n"), + message_count, + total_bytes, + (((double) total_bytes * 8) / et.real_time) / (double) (1024 * 1024), + (et.real_time / (double) message_count) * 1000000, + messages_per_sec < 0 ? 0 : messages_per_sec)); + + // Close new endpoint (listening endpoint stays open). + new_stream.close (); + + delete [] request; + return 0; +} + +static int +run_event_loop (u_short port) +{ + // Raise the socket handle limit to the maximum. + ACE::set_handle_limit (); + + // Create the oneway and twoway acceptors. + ACE_SOCK_Acceptor twoway_acceptor; + ACE_SOCK_Acceptor oneway_acceptor; + + // Create the oneway and twoway server addresses. + ACE_INET_Addr twoway_server_addr (port); + ACE_INET_Addr oneway_server_addr (port + 1); + + // Create acceptors, reuse the address. + if (twoway_acceptor.open (twoway_server_addr, 1) == -1 + || oneway_acceptor.open (oneway_server_addr, 1) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "open"), + 1); + // Check to see what addresses we actually got bound to! + else if (twoway_acceptor.get_local_addr (twoway_server_addr) == -1 + || oneway_acceptor.get_local_addr (oneway_server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "get_local_addr"), + 1); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) starting twoway server at port %d and oneway server at port %d\n", + twoway_server_addr.get_port_number (), + oneway_server_addr.get_port_number ())); + + // Keep these objects out here to prevent excessive constructor + // calls within the loop. + ACE_SOCK_Stream new_stream; + + ACE_Handle_Set handle_set; + handle_set.set_bit (twoway_acceptor.get_handle ()); + handle_set.set_bit (oneway_acceptor.get_handle ()); + + // Performs the iterative server activities. + + for (;;) + { + ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT); + ACE_Handle_Set temp = handle_set; + + int result = ACE_OS::select (int (oneway_acceptor.get_handle ()) + 1, + (fd_set *) temp, + 0, + 0, + timeout); + if (result == -1) + ACE_ERROR ((LM_ERROR, + "(%P|%t) %p\n", + "select")); + else if (result == 0 && verbose) + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) select timed out\n")); + else + { + if (temp.is_set (twoway_acceptor.get_handle ())) + { + if (twoway_acceptor.accept (new_stream) == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "accept")); + continue; + } + else + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) spawning twoway server\n")); + + // Run the twoway server. + run_server (twoway_server, + new_stream.get_handle ()); + } + if (temp.is_set (oneway_acceptor.get_handle ())) + { + if (oneway_acceptor.accept (new_stream) == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "accept")); + continue; + } + else + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) spawning oneway server\n")); + + // Run the oneway server. + run_server (oneway_server, + new_stream.get_handle ()); + } + } + } + + /* NOTREACHED */ +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + u_short port = ACE_DEFAULT_SERVER_PORT; + + if (argc > 1) + port = ACE_OS::atoi (argv[1]); + + return run_event_loop (port); +} diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/CPP-memclient.cpp b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-memclient.cpp new file mode 100644 index 00000000000..3d297f116c0 --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-memclient.cpp @@ -0,0 +1,53 @@ +// $Id$ + +// This tests the features of the <ACE_MEM_Connector> and +// <ACE_MEM_Stream> classes. In addition, it can be used to test the +// oneway and twoway latency and throughput at the socket-level. This +// is useful as a baseline to compare against ORB-level performance +// for the same types of data. + +#include "ace/OS_NS_string.h" +#include "ace/MEM_Connector.h" +#include "ace/INET_Addr.h" +#include "ace/Thread_Manager.h" +#include "ace/Singleton.h" +#include "ace/Get_Opt.h" +#include "ace/High_Res_Timer.h" + + +ACE_RCSID(SOCK_SAP, CPP_inclient, "$Id$") + +static int +run_client (void) +{ + ACE_MEM_Connector connector; + ACE_MEM_Stream stream; + ACE_MEM_Addr server_addr (ACE_DEFAULT_SERVER_PORT); + + if (connector.connect (stream, server_addr.get_remote_addr ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), + ACE_TEXT ("connect")), -1); + + char buf [MAXPATHLEN]; + while (ACE_OS::fgets (buf, MAXPATHLEN, stdin) >0) + { + stream.send (buf, ACE_OS::strlen (buf)+1); + stream.recv (buf, MAXPATHLEN); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Echo: %C\n"), buf)); + } + + return 0; +} + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_UNUSED_ARG(argc); + // Initialize the logger. + ACE_LOG_MSG->open (argv[0]); + + // Run the client + run_client (); + + return 0; +} + diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/CPP-memserver.cpp b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-memserver.cpp new file mode 100644 index 00000000000..4ef76e51b38 --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-memserver.cpp @@ -0,0 +1,70 @@ +// $Id$ + +// This example tests the features of the <ACE_MEM_Acceptor>, +// <ACE_MEM_Stream>, and <ACE_Svc_Handler> classes. If the platform +// supports threads it uses a thread-per-connection concurrency model. +// Otherwise, it uses a single-threaded iterative server model. + +#include "ace/MEM_Acceptor.h" +#include "ace/Thread_Manager.h" +#include "ace/Handle_Set.h" +#include "ace/Profile_Timer.h" + +ACE_RCSID(SOCK_SAP, CPP_inserver, "$Id$") + +static int +run_event_loop (u_short port) +{ + // Create the acceptors. + ACE_MEM_Acceptor acceptor; + + ACE_MEM_Addr server_addr (port); + + // Create acceptors, reuse the address. + if (acceptor.open (server_addr, 1) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "open"), + 1); + else if (acceptor.get_local_addr (server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "get_local_addr"), + 1); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) starting server at port %d\n", + server_addr.get_port_number ())); + + // Keep these objects out here to prevent excessive constructor + // calls within the loop. + ACE_MEM_Stream new_stream; + + // blocking wait on accept. + if (acceptor.accept (new_stream) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "accept"), + -1); + + char buf[MAXPATHLEN]; + int len = 0; + while ((len = new_stream.recv (buf, MAXPATHLEN)) != -1) + { + ACE_DEBUG ((LM_DEBUG, "%s\n", buf)); + new_stream.send (buf, len); + } + + return new_stream.fini (); +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + u_short port = ACE_DEFAULT_SERVER_PORT; + + if (argc > 1) + port = ACE_OS::atoi (argv[1]); + + return run_event_loop (port); +} diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/CPP-unclient.cpp b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-unclient.cpp new file mode 100644 index 00000000000..9f3fdec22b9 --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-unclient.cpp @@ -0,0 +1,71 @@ +// $Id$ + +// ACE_LSOCK Client. + +#include "ace/LSOCK_Connector.h" +#include "ace/UNIX_Addr.h" +#include "ace/Log_Msg.h" +#include "ace/OS_main.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID(SOCK_SAP, CPP_unclient, "$Id$") + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + const ACE_TCHAR *rendezvous = argc > 1 ? argv[1] : ACE_DEFAULT_RENDEZVOUS; + char buf[BUFSIZ]; + + ACE_LSOCK_Stream cli_stream; + ACE_LSOCK_Connector con; + ACE_UNIX_Addr remote_addr (rendezvous); + + // Establish the connection with server. + if (con.connect (cli_stream, remote_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("connect")), + 1); + + // Send data to server (correctly handles "incomplete writes"). + + for (int r_bytes; + (r_bytes = ACE_OS::read (ACE_STDIN, buf, sizeof buf)) > 0; + ) + if (cli_stream.send_n (buf, r_bytes) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("send_n")), + 1); + + // Explicitly close the writer-side of the connection. + if (cli_stream.close_writer () == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("close_writer")), + 1); + + // Wait for handshake with server. + if (cli_stream.recv_n (buf, 1) != 1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("recv_n")), + 1); + + // Close the connection completely. + if (cli_stream.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("close")), + 1); + return 0; +} +#else +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "this platform does not support UNIX-domain sockets\n"), -1); +} +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/CPP-unserver.cpp b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-unserver.cpp new file mode 100644 index 00000000000..cddfe787d92 --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/CPP-unserver.cpp @@ -0,0 +1,159 @@ +// $Id$ + +// This example tests the features of the ACE_LSOCK_Acceptor and +// ACE_LSOCK_Stream classes. If the platform supports threads it uses +// a thread-per-request concurrency model. + +#include "ace/LSOCK_Acceptor.h" +#include "ace/Thread_Manager.h" +#include "ace/OS_main.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID(SOCK_SAP, CPP_unserver, "$Id$") + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +// Are we running verbosely? +static int verbose = 1; + +// Entry point into the server task. + +static void * +server (void *arg) +{ + ACE_UNIX_Addr cli_addr; + ACE_LSOCK_Stream new_stream; + ACE_HANDLE handle = (ACE_HANDLE) (long) arg; + + new_stream.set_handle (handle); + + // Make sure we're not in non-blocking mode. + if (new_stream.disable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("disable")), + 0); + + if (new_stream.get_remote_addr (cli_addr) == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("get_remote_addr"))); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) client connected from %C\n"), + cli_addr.get_path_name ())); + + // Read data from client (terminate on error). + + for (;;) + { + char buf[BUFSIZ]; + + ssize_t r_bytes = new_stream.recv (buf, sizeof buf); + + if (r_bytes == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("recv"))); + break; + + } + else if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) reached end of input, connection closed by client\n"))); + break; + } + else if (verbose && ACE::write_n (ACE_STDOUT, buf, r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::write_n"))); + else if (new_stream.send_n (buf, r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("send_n"))); + } + + // Close new endpoint (listening endpoint stays open). + if (new_stream.close () == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("close"))); + + return 0; +} + +static int +run_event_loop (const ACE_TCHAR rendezvous[]) +{ + ACE_LSOCK_Acceptor peer_acceptor; + + // Create a server address. + ACE_UNIX_Addr server_addr (rendezvous); + + ACE_OS::unlink (rendezvous); + + // Create a server. + + if (peer_acceptor.open (server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("open")), + 1); + else if (peer_acceptor.get_local_addr (server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("get_local_addr")), + -1); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("starting server %C\n"), + server_addr.get_path_name ())); + + // Keep these guys out here to prevent excessive constructor + // calls... + ACE_LSOCK_Stream new_stream; + + // Performs the iterative server activities. + + for (;;) + { + ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT); + + if (peer_acceptor.accept (new_stream, 0, &timeout) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("accept"))); + continue; + } + +#if defined (ACE_HAS_THREADS) + if (ACE_Thread_Manager::instance ()->spawn ((ACE_THR_FUNC) server, + reinterpret_cast<void *> (new_stream.get_handle ()), + THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("spawn")), + 1); +#else + server (reinterpret_cast<void *> (new_stream.get_handle ())); +#endif /* ACE_HAS_THREADS */ + } + + ACE_NOTREACHED (return 0;) +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + return run_event_loop (argc > 1 ? argv[1] : ACE_DEFAULT_RENDEZVOUS); +} +#else +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "this platform does not support UNIX-domain sockets\n"), -1); +} +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/FD-unclient.cpp b/ACE/examples/IPC_SAP/SOCK_SAP/FD-unclient.cpp new file mode 100644 index 00000000000..80c614ca987 --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/FD-unclient.cpp @@ -0,0 +1,62 @@ +// $Id$ + +#include "ace/OS_NS_fcntl.h" +#include "ace/LSOCK_Connector.h" +#include "ace/UNIX_Addr.h" +#include "ace/Log_Msg.h" +#include "ace/OS_main.h" + +ACE_RCSID(SOCK_SAP, FD_unclient, "$Id$") + +#if defined (ACE_HAS_MSG) && !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) +// ACE_LSOCK Client. + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + const ACE_TCHAR *file_name = argc > 1 ? argv[1] : ACE_TEXT ("./local_data"); + const ACE_TCHAR *rendezvous = argc > 2 ? argv[2] : ACE_DEFAULT_RENDEZVOUS; + + ACE_LSOCK_Stream cli_stream; + ACE_UNIX_Addr addr (rendezvous); + + // Establish the connection with server. + ACE_LSOCK_Connector connector; + + if (connector.connect (cli_stream, addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p"), ACE_TEXT ("connect")), -1); + + ACE_HANDLE handle = ACE_OS::open (file_name, O_RDONLY); + + if (handle == ACE_INVALID_HANDLE) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p"), ACE_TEXT ("open")), -1); + + // Send handle to server (correctly handles incomplete writes). + if (cli_stream.send_handle (handle) == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p"), ACE_TEXT ("send")), -1); + + char buf[BUFSIZ]; + ssize_t n = cli_stream.recv (buf, sizeof buf); + + if (n == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p"), ACE_TEXT ("recv")), -1); + else if (n == 0) + //FUZZ: disable check_for_lack_ACE_OS + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("server shutdown (bug in kernel?)\n"))); + //FUZZ: enable check_for_lack_ACE_OS + else + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("server %*C shutdown\n"), n, buf)); + + // Explicitly close the connection. + if (cli_stream.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p"), ACE_TEXT ("close")), -1); + + return 0; +} +#else +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("your platform must support sendmsg/recvmsg to run this test\n")), -1); +} +#endif /* ACE_HAS_MSG */ diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/FD-unserver.cpp b/ACE/examples/IPC_SAP/SOCK_SAP/FD-unserver.cpp new file mode 100644 index 00000000000..b629b9f0dd8 --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/FD-unserver.cpp @@ -0,0 +1,100 @@ +// $Id$ + +#include "ace/LSOCK_Acceptor.h" +#include "ace/LSOCK_Stream.h" +#include "ace/UNIX_Addr.h" +#include "ace/Log_Msg.h" +#include "ace/OS_main.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_unistd.h" +#include "ace/OS_NS_stdlib.h" + +ACE_RCSID(SOCK_SAP, FD_unserver, "$Id$") + +#if !defined (ACE_LACKS_UNIX_DOMAIN_SOCKETS) + +// ACE_LSOCK Server + +void +handle_client (ACE_LSOCK_Stream &stream) +{ + char buf[BUFSIZ]; + ACE_HANDLE handle; + + // Retrieve the socket descriptor passed from the client. + + if (stream.recv_handle (handle) == -1) + ACE_ERROR ((LM_ERROR, "%p", "recv_handle")); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) ----------------------------------------\n")); + + // Read data from client (correctly handles incomplete reads due to + // flow control). + + for (ssize_t n; + (n = ACE_OS::read (handle, buf, sizeof buf)) > 0; + ) + ACE_DEBUG ((LM_DEBUG, "%*s", n, buf)); + + ACE_OS::sprintf (buf, "%d", static_cast<int> (ACE_OS::getpid ())); + + ACE_DEBUG ((LM_DEBUG, "(%s, %d) ----------------------------------------\n", buf, ACE_OS::strlen (buf))); + + // Tell the client to shut down. + if (stream.send_n (buf, ACE_OS::strlen (buf)) == -1) + ACE_ERROR ((LM_ERROR, "%p", "send")); + + // Close new endpoint (listening endpoint stays open). + if (stream.close () == -1) + ACE_ERROR ((LM_ERROR, "%p", "close")); +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + const ACE_TCHAR *rendezvous = argc > 1 ? argv[1] : ACE_DEFAULT_RENDEZVOUS; + // Create a server. + ACE_OS::unlink (rendezvous); + ACE_UNIX_Addr addr (rendezvous); + ACE_LSOCK_Acceptor peer_acceptor (addr); + ACE_LSOCK_Stream stream; + + // Performs the concurrent server activities. + + for (;;) + { + // Create a new ACE_SOCK_Stream endpoint. + if (peer_acceptor.accept (stream) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "accept"), -1); + + ACE_DEBUG ((LM_DEBUG, "(%P|%t) accepted new connection\n")); + +#if defined (VXWORKS) + handle_client (stream); +#else + switch (ACE_OS::fork (argv[0])) + { + case -1: + ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "fork"), -1); + /* NOTREACHED */ + case 0: + ACE_LOG_MSG->sync (argv[0]); + handle_client (stream); + ACE_OS::exit (0); + /* NOTREACHED */ + default: + stream.close (); + } +#endif /* VXWORKS */ + } + + ACE_NOTREACHED (return 0;) +} +#else +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, "your platform doesn't not support UNIX domain sockets\n"), -1); +} +#endif /* ACE_LACKS_UNIX_DOMAIN_SOCKETS */ diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/Makefile.am b/ACE/examples/IPC_SAP/SOCK_SAP/Makefile.am new file mode 100644 index 00000000000..803dc5bbf7f --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/Makefile.am @@ -0,0 +1,188 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + + +## Makefile.Sock_Sap_CPP_Inclient.am + +noinst_PROGRAMS = CPP-inclient + +CPP_inclient_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +CPP_inclient_SOURCES = \ + CPP-inclient.cpp \ + CPP-inclient.h + +CPP_inclient_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Sock_Sap_CPP_Inserver.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += CPP-inserver + +CPP_inserver_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +CPP_inserver_SOURCES = \ + CPP-inserver.cpp \ + CPP-inclient.h \ + CPP-inserver-fancy.h + +CPP_inserver_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Sock_Sap_CPP_Memclient.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += CPP-memclient + +CPP_memclient_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +CPP_memclient_SOURCES = \ + CPP-memclient.cpp \ + CPP-inclient.h \ + CPP-inserver-fancy.h + +CPP_memclient_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Sock_Sap_CPP_Memserver.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += CPP-memserver + +CPP_memserver_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +CPP_memserver_SOURCES = \ + CPP-memserver.cpp \ + CPP-inclient.h \ + CPP-inserver-fancy.h + +CPP_memserver_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Sock_Sap_CPP_Unclient.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += CPP-unclient + +CPP_unclient_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +CPP_unclient_SOURCES = \ + CPP-unclient.cpp \ + CPP-inclient.h \ + CPP-inserver-fancy.h + +CPP_unclient_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Sock_Sap_CPP_Unserver.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += CPP-unserver + +CPP_unserver_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +CPP_unserver_SOURCES = \ + CPP-unserver.cpp \ + CPP-inclient.h \ + CPP-inserver-fancy.h + +CPP_unserver_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.Sock_Sap_C_Inclient.am + +noinst_PROGRAMS += C-inclient + +C_inclient_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +C_inclient_SOURCES = \ + C-inclient.cpp \ + CPP-inclient.h \ + CPP-inserver-fancy.h + +C_inclient_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Sock_Sap_C_Inserver.am + +noinst_PROGRAMS += C-inserver + +C_inserver_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +C_inserver_SOURCES = \ + C-inserver.cpp \ + CPP-inclient.h \ + CPP-inserver-fancy.h + +C_inserver_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.Sock_Sap_FD_Unclient.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += FD-unclient + +FD_unclient_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +FD_unclient_SOURCES = \ + FD-unclient.cpp \ + CPP-inclient.h \ + CPP-inserver-fancy.h + +FD_unclient_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/README b/ACE/examples/IPC_SAP/SOCK_SAP/README new file mode 100644 index 00000000000..bbe0f20ce5a --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/README @@ -0,0 +1,46 @@ +This directory contains groups of client and server test programs that +exercise the various C++ wrappers for sockets. In general, the test +programs do more or less the same thing -- the client establishes a +connection with the server and then transfers data to the server, +which keeps printing the data until EOF is reached (e.g., user types +^D). + +Unless noted differently, the server is implemented as an "iterative +server," i.e., it only deals with one client at a time. The following +describes each set of tests in more detail: + + . C-{inclient,inserver}.cpp -- This is basically a C code + implementation that opens a connection to the server and + sends all the data from the stdin using Internet domain + sockets (i.e., TCP). + + . CPP-{inclient,inserver}.cpp -- This test is + a more sophisticated C++ wrapper version of the preceeding + "C" test using Internet domain sockets (i.e., TCP). + It allows you to test oneway and twoway socket communication + latency and throughput between two processes on the same + machine or on different machines. + + . CPP-inserver-fancy.cpp -- This program is a more glitzy + version of CPP-inserver.cpp that illustrates additional + features of ACE, such as ACE_Svc_Handler. + + . CPP-inserver-poll.cpp -- This test illustrates how to + write single-threaded concurrent servers using UNIX SVR4 + poll(). You can run this test using the CPP-inclient.cpp + program as the oneway client. + + . CPP-{unclient,unserver}.cpp -- This test is basically + a C++ wrapper version of the preceeding "C++" test using + UNIX domain sockets. Note that this test only works + between a client and server process on the same machine. + + . FD-{unclient,inclient}.cpp -- This test illustrates + how to pass file descriptors between a client and a + concurrent server process on the same machine using the ACE + C++ wrappers for UNIX domain sockets. + +For examples of the ACE SOCK_{Dgram,CODgram} and +SOCK_Dgram_{Mcast,Bcast} wrappers, please take a look in the +./examples/Reactor/{Dgram,Multicast,Ntalker} directories. + diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/local_data b/ACE/examples/IPC_SAP/SOCK_SAP/local_data new file mode 100644 index 00000000000..c0119859a28 --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/local_data @@ -0,0 +1 @@ +I am Iron man! diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/run_test b/ACE/examples/IPC_SAP/SOCK_SAP/run_test new file mode 100755 index 00000000000..7f0a4dbdaa7 --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/run_test @@ -0,0 +1,36 @@ +#! /bin/sh +# $Id$ +# +# Spawns CPP-inserver-fancy and CPP-inclient executables on a single host. + +usage="usage: $0 #client_threads" + +user=`whoami` +iterations=1000 + +if [ $# -ne 1 ]; then + echo $usage; + exit 1 +fi +threads=$1; + + +######## +######## Enable signal handler. +######## +trap 'kill -1 $server_pid; ' 0 1 2 15 + + +######## +######## Start CPP-inserver-fancy and save its pid. +######## +./CPP-inserver-fancy > \ + ${tmp}server.log 2>&1 & +server_pid=$! + +sleep 2; + +######## +######## Start CPP-inclient. +######## +./CPP-inclient -2 -T 100000 -m 69 -t $threads -i 100 > ${tmp}client-${threads}.log 2>&1 diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/sock_sap.mpc b/ACE/examples/IPC_SAP/SOCK_SAP/sock_sap.mpc new file mode 100644 index 00000000000..e2081ed7652 --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/sock_sap.mpc @@ -0,0 +1,73 @@ +// -*- MPC -*- +// $Id$ + +project(*C_inclient) : aceexe { + exename = C-inclient + Source_Files { + C-inclient.cpp + } +} + +project(*C_inserver) : aceexe { + avoids += wince + exename = C-inserver + Source_Files { + C-inserver.cpp + } +} + +project(*CPP_inclient) : aceexe { + exename = CPP-inclient + Source_Files { + CPP-inclient.cpp + } +} + +project(*CPP_inserver) : aceexe { + avoids += ace_for_tao + exename = CPP-inserver + Source_Files { + CPP-inserver.cpp + } +} + +project(*CPP_memclient) : aceexe { + avoids += ace_for_tao + exename = CPP-memclient + Source_Files { + CPP-memclient.cpp + } +} + +project(*CPP_memserver) : aceexe { + avoids += ace_for_tao + exename = CPP-memserver + Source_Files { + CPP-memserver.cpp + } +} + +project(*FD_unclient) : aceexe { + avoids += ace_for_tao + exename = FD-unclient + Source_Files { + FD-unclient.cpp + } +} + +project(*CPP_unclient) : aceexe { + avoids += ace_for_tao + exename = CPP-unclient + Source_Files { + CPP-unclient.cpp + } +} + +project(*CPP_unserver) : aceexe { + avoids += ace_for_tao + exename = CPP-unserver + Source_Files { + CPP-unserver.cpp + } +} + diff --git a/ACE/examples/IPC_SAP/SOCK_SAP/summarize b/ACE/examples/IPC_SAP/SOCK_SAP/summarize new file mode 100755 index 00000000000..ee8ffd2df25 --- /dev/null +++ b/ACE/examples/IPC_SAP/SOCK_SAP/summarize @@ -0,0 +1,45 @@ +eval '(exit $?0)' && eval 'exec perl -w -S $0 ${1+"$@"}' + & eval 'exec perl -w -S $0 $argv:q' + if 0; + +# $Id$ +# +# Summarizes results from a series of runs of run_test, with +# different numbers of clients. Example usage: +# +# $ for i in 1 2 5 10 15 20 25 30 35 40 45 50; do ./run_test $i; done +# $ ./summarize +# +# The first three lines above let this script run without specifying the +# full path to perl, as long as it is in the user's PATH. +# Taken from perlrun man page. + +@files = glob 'client-*.log'; +@total_threads = (); + +foreach $file (@files) { + my ($i); + ($i = $file) =~ s/client-(\d+).log/$1/; + push @total_threads, $i; +} + +print "No.of threads\t\tAverage Latency\n\n"; + +foreach $total_threads (sort {$a <=> $b} @total_threads) { + undef $high_latency; + + $high_latency = 0; + open (FILE, "client-${total_threads}.log") || + die "$0: unable to open \"client-${total_threads}.log\"\n"; + while ($line = <FILE>) { + if ($line =~ /.*usec-per-message = ([\d\.]+)/) + { + $high_latency += $1 ; + $number++; + } + } + close FILE; + + printf "%3d\t\t\t%8f\n", + $total_threads, $high_latency/$number; +} diff --git a/ACE/examples/IPC_SAP/SPIPE_SAP/Makefile.am b/ACE/examples/IPC_SAP/SPIPE_SAP/Makefile.am new file mode 100644 index 00000000000..9979c8a5751 --- /dev/null +++ b/ACE/examples/IPC_SAP/SPIPE_SAP/Makefile.am @@ -0,0 +1,140 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +## Makefile.SPIPE_SAP_Client.am + +noinst_PROGRAMS = client + +client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +client_SOURCES = \ + client.cpp \ + shared.h + +client_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.SPIPE_SAP_Consumer_Msg.am + +noinst_PROGRAMS += consumer_msg + +consumer_msg_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +consumer_msg_SOURCES = \ + consumer_msg.cpp \ + shared.h + +consumer_msg_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.SPIPE_SAP_Consumer_Read.am + +noinst_PROGRAMS += consumer_read + +consumer_read_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +consumer_read_SOURCES = \ + consumer_read.cpp \ + shared.h + +consumer_read_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.SPIPE_SAP_NPClient.am + +noinst_PROGRAMS += NPClient + +NPClient_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +NPClient_SOURCES = \ + NPClient.cpp \ + shared.h + +NPClient_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.SPIPE_SAP_NPServer.am + +noinst_PROGRAMS += NPServer + +NPServer_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +NPServer_SOURCES = \ + NPServer.cpp \ + shared.h + +NPServer_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.SPIPE_SAP_Producer_Msg.am + +noinst_PROGRAMS += producer_msg + +producer_msg_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +producer_msg_SOURCES = \ + producer_msg.cpp \ + shared.h + +producer_msg_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.SPIPE_SAP_Producer_Read.am + +noinst_PROGRAMS += producer_read + +producer_read_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +producer_read_SOURCES = \ + producer_read.cpp \ + shared.h + +producer_read_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.SPIPE_SAP_Server.am + +noinst_PROGRAMS += server + +server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +server_SOURCES = \ + server.cpp \ + shared.h + +server_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/IPC_SAP/SPIPE_SAP/NPClient.cpp b/ACE/examples/IPC_SAP/SPIPE_SAP/NPClient.cpp new file mode 100644 index 00000000000..e7c6c5904aa --- /dev/null +++ b/ACE/examples/IPC_SAP/SPIPE_SAP/NPClient.cpp @@ -0,0 +1,62 @@ +// $Id$ + +#include "ace/OS_main.h" +#include "ace/SPIPE_Addr.h" +#include "ace/SPIPE_Connector.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_Memory.h" + +ACE_RCSID(SPIPE_SAP, NPClient, "$Id$") + +#if defined (ACE_WIN32) +#define MAKE_PIPE_NAME(X) ACE_TEXT ("\\\\.\\pipe\\") ACE_TEXT (X) +#else +#define MAKE_PIPE_NAME(X) ACE_TEXT (X) +#endif + +const int DEFAULT_SIZE = 8; +const int DEFAULT_COUNT = 10000; + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + int size = argc > 1 ? ACE_OS::atoi (argv[1]) : DEFAULT_SIZE; + int iterations = argc > 2 ? ACE_OS::atoi (argv[2]) : DEFAULT_COUNT; + char *buf; + + ACE_NEW_RETURN (buf, + char[size], + 1); + + const ACE_TCHAR *rendezvous = MAKE_PIPE_NAME ("acepipe"); + + ACE_SPIPE_Stream cli_stream; + ACE_SPIPE_Connector con; + int i; + + if (con.connect (cli_stream, + ACE_SPIPE_Addr (rendezvous)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + rendezvous), + -1); + + ACE_OS::strcpy (buf, "hello"); + size = ACE_OS::strlen (buf) + 1; + + for (i = 0; i < iterations; i++) + if (cli_stream.send (buf, size) != size) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("putmsg")), + -1); + + if (cli_stream.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("close")), + -1); + return 0; +} diff --git a/ACE/examples/IPC_SAP/SPIPE_SAP/NPServer.cpp b/ACE/examples/IPC_SAP/SPIPE_SAP/NPServer.cpp new file mode 100644 index 00000000000..4055a2cc02d --- /dev/null +++ b/ACE/examples/IPC_SAP/SPIPE_SAP/NPServer.cpp @@ -0,0 +1,67 @@ +// $Id$ + +#include "ace/SPIPE_Addr.h" +#include "ace/SPIPE_Acceptor.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID(SPIPE_SAP, NPServer, "$Id$") + +#if defined (ACE_WIN32) +#define MAKE_PIPE_NAME(X) ACE_TEXT ("\\\\.\\pipe\\") ACE_TEXT (X) +#else +#define MAKE_PIPE_NAME(X) ACE_TEXT (X) +#endif + +int +ACE_TMAIN (int /* argc */, ACE_TCHAR * /* argv */ []) +{ + ACE_SPIPE_Acceptor acceptor; + ACE_SPIPE_Stream new_stream; + char buf[BUFSIZ]; + int n; + const ACE_TCHAR *rendezvous = MAKE_PIPE_NAME ("acepipe"); + + // Initialize named pipe listener. + + if (acceptor.open (ACE_SPIPE_Addr (rendezvous)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("open")), 1); + + for (;;) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("waiting for connection\n"))); + + // Accept a client connection. + if (acceptor.accept (new_stream, 0) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("accept")), + 1); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("Accepted connection\n"))); + + while ((n = new_stream.recv (buf, sizeof buf)) > 0) + { + ACE_OS::fprintf (stderr, + "%s\n", + buf); + ACE_OS::write (ACE_STDOUT, + buf, + n); + } + + if (n == -1) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("End of connection. Closing handle\n"))); + new_stream.close (); + } + } + + ACE_NOTREACHED(return 0); +} diff --git a/ACE/examples/IPC_SAP/SPIPE_SAP/SPIPE_SAP.mpc b/ACE/examples/IPC_SAP/SPIPE_SAP/SPIPE_SAP.mpc new file mode 100644 index 00000000000..3f0d7318b3e --- /dev/null +++ b/ACE/examples/IPC_SAP/SPIPE_SAP/SPIPE_SAP.mpc @@ -0,0 +1,58 @@ +// -*- MPC -*- +// $Id$ + +project(*client) : aceexe { + exename = client + Source_Files { + client.cpp + } +} + +project(*consumer_msg) : aceexe { + exename = consumer_msg + Source_Files { + consumer_msg.cpp + } +} + +project(*consumer_read) : aceexe { + exename = consumer_read + Source_Files { + consumer_read.cpp + } +} + +project(*NPClient) : aceexe { + exename = NPClient + Source_Files { + NPClient.cpp + } +} + +project(*NPServer) : aceexe { + exename = NPServer + Source_Files { + NPServer.cpp + } +} + +project(*producer_msg) : aceexe { + exename = producer_msg + Source_Files { + producer_msg.cpp + } +} + +project(*producer_read) : aceexe { + exename = producer_read + Source_Files { + producer_read.cpp + } +} + +project(*server) : aceexe { + exename = server + Source_Files { + server.cpp + } +} diff --git a/ACE/examples/IPC_SAP/SPIPE_SAP/client.cpp b/ACE/examples/IPC_SAP/SPIPE_SAP/client.cpp new file mode 100644 index 00000000000..ad0ee029dbd --- /dev/null +++ b/ACE/examples/IPC_SAP/SPIPE_SAP/client.cpp @@ -0,0 +1,48 @@ +// $Id$ + +#include "ace/OS_main.h" +#include "ace/SPIPE_Addr.h" +#include "ace/SPIPE_Connector.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" + +ACE_RCSID(SPIPE_SAP, client, "$Id$") + +#if defined (ACE_HAS_STREAM_PIPES) + +#include "shared.h" + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc < 2) + ACE_ERROR_RETURN ((LM_ERROR, "usage: %s string [rendezvous]\n", argv[0]), 1); + + if (argc > 2) + rendezvous = argv[2]; + + ACE_SPIPE_Stream cli_stream; + ACE_SPIPE_Connector con; + + if (con.connect (cli_stream, ACE_SPIPE_Addr (rendezvous)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", rendezvous), 1); + + ssize_t len = ACE_OS::strlen (argv[1]) + 1; + + if (cli_stream.send (argv[1], len) != len) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), 1); + + if (cli_stream.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), 1); + + return 0; +} +#else +#include <stdio.h> +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::fprintf (stderr, "This feature is not supported\n"); + return 0; +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/ACE/examples/IPC_SAP/SPIPE_SAP/consumer_msg.cpp b/ACE/examples/IPC_SAP/SPIPE_SAP/consumer_msg.cpp new file mode 100644 index 00000000000..daadc20fdf0 --- /dev/null +++ b/ACE/examples/IPC_SAP/SPIPE_SAP/consumer_msg.cpp @@ -0,0 +1,59 @@ +// $Id$ + +#include "ace/OS_main.h" +#include "ace/SPIPE_Addr.h" +#include "ace/SPIPE_Acceptor.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Time_Value.h" + +ACE_RCSID(SPIPE_SAP, consumer_msg, "$Id$") + +#if defined (ACE_HAS_STREAM_PIPES) + +#include "shared.h" + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_SPIPE_Acceptor peer_acceptor; + ACE_SPIPE_Stream new_stream; + char buf[BUFSIZ]; + ACE_Str_Buf buffer (buf, 0, sizeof buf); + int flags = 0; + + if (argc > 1) + rendezvous = argv[1]; + + ACE_OS::unlink (rendezvous); + ACE_OS::fdetach (ACE_TEXT_ALWAYS_CHAR (rendezvous)); + + ACE_SPIPE_Addr addr (rendezvous); + ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT); + + if (peer_acceptor.open (addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), 1); + + ACE_DEBUG ((LM_DEBUG, "waiting for connection\n")); + + if (peer_acceptor.accept (new_stream, 0, &timeout) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "accept"), 1); + + ACE_DEBUG ((LM_DEBUG, "accepted\n")); + + while (new_stream.recv ((ACE_Str_Buf *) 0, &buffer, &flags) >= 0) + if (buffer.len == 0) + break; + else + ACE_OS::write (ACE_STDOUT, buffer.buf, buffer.len); + return 0; +} +#else +#include <stdio.h> +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::fprintf (stderr, "This feature is not supported\n"); + return 0; +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/ACE/examples/IPC_SAP/SPIPE_SAP/consumer_read.cpp b/ACE/examples/IPC_SAP/SPIPE_SAP/consumer_read.cpp new file mode 100644 index 00000000000..f16c0683680 --- /dev/null +++ b/ACE/examples/IPC_SAP/SPIPE_SAP/consumer_read.cpp @@ -0,0 +1,56 @@ +// $Id$ + +#include "ace/OS_main.h" +#include "ace/SPIPE_Addr.h" +#include "ace/SPIPE_Acceptor.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Time_Value.h" + +ACE_RCSID(SPIPE_SAP, consumer_read, "$Id$") + +#if defined (ACE_HAS_STREAM_PIPES) + +#include "shared.h" + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_SPIPE_Acceptor peer_acceptor; + ACE_SPIPE_Stream new_stream; + char buf[BUFSIZ]; + int n; + + // Wait up to ACE_DEFAULT_TIMEOUT seconds to accept connection. + ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT); + + if (argc > 1) + rendezvous = argv[1]; + + ACE_OS::unlink (rendezvous); + ACE_OS::fdetach (ACE_TEXT_ALWAYS_CHAR (rendezvous)); + + if (peer_acceptor.open (ACE_SPIPE_Addr (rendezvous)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), 1); + + ACE_DEBUG ((LM_DEBUG, "waiting for connection\n")); + + if (peer_acceptor.accept (new_stream, 0, &timeout) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "accept"), 1); + + ACE_DEBUG ((LM_DEBUG, "accepted\n")); + + while ((n = new_stream.recv (buf, sizeof buf)) > 0) + ACE_OS::write (ACE_STDOUT, buf, n); + + return 0; +} +#else +#include <stdio.h> +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::fprintf (stderr, "This feature is not supported\n"); + return 0; +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/ACE/examples/IPC_SAP/SPIPE_SAP/producer_msg.cpp b/ACE/examples/IPC_SAP/SPIPE_SAP/producer_msg.cpp new file mode 100644 index 00000000000..619a44f1e71 --- /dev/null +++ b/ACE/examples/IPC_SAP/SPIPE_SAP/producer_msg.cpp @@ -0,0 +1,66 @@ +// $Id$ + +#include "ace/OS_main.h" +#include "ace/OS_Memory.h" +#include "ace/SPIPE_Addr.h" +#include "ace/SPIPE_Connector.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Time_Value.h" + +ACE_RCSID(SPIPE_SAP, producer_msg, "$Id$") + +#if defined (ACE_HAS_STREAM_PIPES) + +#include "shared.h" + +const int DEFAULT_SIZE = 4 * 1024; +const int DEFAULT_COUNT = 100; + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + int size = argc > 1 ? ACE_OS::atoi (argv[1]) : DEFAULT_SIZE; + int iterations = argc > 2 ? ACE_OS::atoi (argv[2]) : DEFAULT_COUNT; + char *buf; + + ACE_NEW_RETURN (buf, char[size], -1); + + if (argc > 3) + rendezvous = argv[3]; + + ACE_SPIPE_Stream cli_stream; + ACE_SPIPE_Connector con; + int i; + + if (con.connect (cli_stream, ACE_SPIPE_Addr (rendezvous)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", rendezvous), 1); + + for (i = 0; i < size; i++) + buf[i] = 'a'; + + ACE_Str_Buf buffer (buf, size); + + for (i = 0; i < iterations; i++) + if (cli_stream.send ((ACE_Str_Buf *) 0, + &buffer, + 1, + MSG_BAND) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), 1); + + if (cli_stream.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), 1); + + delete buf; + return 0; +} +#else +#include <stdio.h> +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::fprintf (stderr, "This feature is not supported\n"); + return 0; +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/ACE/examples/IPC_SAP/SPIPE_SAP/producer_read.cpp b/ACE/examples/IPC_SAP/SPIPE_SAP/producer_read.cpp new file mode 100644 index 00000000000..f04f7961818 --- /dev/null +++ b/ACE/examples/IPC_SAP/SPIPE_SAP/producer_read.cpp @@ -0,0 +1,54 @@ +// $Id$ + +#include "ace/OS_main.h" +#include "ace/SPIPE_Addr.h" +#include "ace/SPIPE_Connector.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_stdlib.h" + + +ACE_RCSID(SPIPE_SAP, producer_read, "$Id$") + +#if defined (ACE_HAS_STREAM_PIPES) + +#include "shared.h" + +const int DEFAULT_SIZE = 8 * 1024; +const int DEFAULT_COUNT = 100; + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + int size = argc > 1 ? ACE_OS::atoi (argv[1]) : DEFAULT_SIZE; + int iterations = argc > 2 ? ACE_OS::atoi (argv[2]) : DEFAULT_COUNT; + char *buf = new char[size]; + + if (argc > 3) + rendezvous = argv[3]; + + ACE_SPIPE_Stream cli_stream; + ACE_SPIPE_Connector con; + int i; + + if (con.connect (cli_stream, ACE_SPIPE_Addr (rendezvous)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", rendezvous), -1); + + for (i = 0; i < size; i++) + buf[i] = 'a'; + + for (i = 0; i < iterations; i++) + if (cli_stream.send (buf, size) != size) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "putmsg"), -1); + + if (cli_stream.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); + + return 0; +} +#else +#include <stdio.h> +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, "this feature is not supported"), -1); +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/ACE/examples/IPC_SAP/SPIPE_SAP/server.cpp b/ACE/examples/IPC_SAP/SPIPE_SAP/server.cpp new file mode 100644 index 00000000000..bc582f177eb --- /dev/null +++ b/ACE/examples/IPC_SAP/SPIPE_SAP/server.cpp @@ -0,0 +1,124 @@ +// $Id$ + +#include "ace/OS_main.h" +#include "ace/SPIPE_Addr.h" +#include "ace/SPIPE_Acceptor.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_poll.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID(SPIPE_SAP, server, "$Id$") + +#if defined (ACE_HAS_STREAM_PIPES) + +#include "shared.h" + +// Maximum per-process open I/O descriptors. +const int MAX_HANDLES = 200; + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_SPIPE_Acceptor peer_acceptor; + ACE_SPIPE_Stream new_stream; + struct pollfd poll_array[MAX_HANDLES]; + ACE_HANDLE handle; + + for (handle = 0; handle < MAX_HANDLES; handle++) + { + poll_array[handle].fd = -1; + poll_array[handle].events = POLLIN; + } + + if (argc > 1) + rendezvous = argv[1]; + + ACE_OS::fdetach (ACE_TEXT_ALWAYS_CHAR (rendezvous)); + ACE_SPIPE_Addr addr (rendezvous); + + ACE_HANDLE s_handle = peer_acceptor.open (addr); + + if (s_handle == -1) + ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "peer_acceptor.open"), -1); + + poll_array[0].fd = s_handle; + + for (int width = 1;;) + { + // Block waiting for client I/O events (handle interrupts). + while (ACE_OS::poll (poll_array, width) == -1 && errno == EINTR) + continue; + + // Handle pending logging messages first (s_handle + 1 is + // guaranteed to be lowest client descriptor). + + for (handle = s_handle + 1; handle < width; handle++) + if (ACE_BIT_ENABLED (poll_array[handle].revents, POLLIN) + || ACE_BIT_ENABLED (poll_array[handle].revents, POLLHUP)) + { + char buf[BUFSIZ]; + ssize_t n = ACE_OS::read (handle, buf, sizeof buf); + + // recv will not block in this case! + if (n == -1) + ACE_DEBUG ((LM_DEBUG, "%p\n", "read failed")); + else if (n == 0) + { + // Handle client connection shutdown. + if (ACE_OS::close (poll_array[handle].fd) == -1) + ACE_DEBUG ((LM_DEBUG, "%p\n", "close")); + poll_array[handle].fd = -1; + + if (handle + 1 == width) + { + while (poll_array[handle].fd == -1) + handle--; + width = handle + 1; + } + } + else + ACE_DEBUG ((LM_DEBUG, "%*s\n", n, buf)); + } + + if (ACE_BIT_ENABLED (poll_array[0].revents, POLLIN)) + { + if (peer_acceptor.accept (new_stream) == -1) + ACE_DEBUG ((LM_DEBUG, "%p\n", "accept failed")); + + ACE_SPIPE_Addr client; + ACE_HANDLE n_handle = new_stream.get_handle (); + + if (new_stream.get_remote_addr (client) == -1) + ACE_DEBUG ((LM_DEBUG, "%p\n", + "get_remote_addr failed")); + + ACE_DEBUG ((LM_DEBUG, + "n_handle = %d, uid = %d, gid = %d\n", + n_handle, + client.user_id (), + client.group_id ())); + + int arg = RMSGN | RPROTDAT; + + if (ACE_OS::ioctl (n_handle, + I_SRDOPT, (void *) arg) == -1) + ACE_DEBUG ((LM_DEBUG, "%p\n", "ioctl failed")); + + poll_array[n_handle].fd = n_handle; + + if (n_handle >= width) + width = n_handle + 1; + } + } + + ACE_NOTREACHED (return 0;) +} +#else +#include <stdio.h> +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::fprintf (stderr, "This feature is not supported\n"); + return 0; +} +#endif /* ACE_HAS_STREAM_PIPES */ diff --git a/ACE/examples/IPC_SAP/SPIPE_SAP/shared.h b/ACE/examples/IPC_SAP/SPIPE_SAP/shared.h new file mode 100644 index 00000000000..47f2e8db6bc --- /dev/null +++ b/ACE/examples/IPC_SAP/SPIPE_SAP/shared.h @@ -0,0 +1,10 @@ +/* -*- C++ -*- */ +// $Id$ + +#include "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +static const ACE_TCHAR *rendezvous = ACE_DEFAULT_RENDEZVOUS; diff --git a/ACE/examples/IPC_SAP/SSL_SAP/Makefile.am b/ACE/examples/IPC_SAP/SSL_SAP/Makefile.am new file mode 100644 index 00000000000..5a0e4bc3dfb --- /dev/null +++ b/ACE/examples/IPC_SAP/SSL_SAP/Makefile.am @@ -0,0 +1,196 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.SSL_SAP_Client.am + +if BUILD_SSL +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += client + +client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -DACE_HAS_SSL=1 \ + @ACE_TLS_CPPFLAGS@ + +client_SOURCES = \ + SSL-client.cpp \ + SSL-client.h + +client_LDFLAGS = \ + @ACE_TLS_LDFLAGS@ + +client_LDADD = \ + $(ACE_BUILDDIR)/ace/SSL/libACE_SSL.la \ + $(ACE_BUILDDIR)/ace/libACE.la \ + @ACE_TLS_LIBS@ + +endif !BUILD_ACE_FOR_TAO +endif BUILD_SSL + +## Makefile.SSL_SAP_Client_Simple.am + +if BUILD_SSL +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += client-simple + +client_simple_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -DACE_HAS_SSL=1 \ + @ACE_TLS_CPPFLAGS@ + +client_simple_SOURCES = \ + SSL-client-simple.cpp \ + SSL-client-simple.h + +client_simple_LDFLAGS = \ + @ACE_TLS_LDFLAGS@ + +client_simple_LDADD = \ + $(ACE_BUILDDIR)/ace/SSL/libACE_SSL.la \ + $(ACE_BUILDDIR)/ace/libACE.la \ + @ACE_TLS_LIBS@ + +endif !BUILD_ACE_FOR_TAO +endif BUILD_SSL + +## Makefile.SSL_SAP_Server.am + +if BUILD_SSL +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += server + +server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -DACE_HAS_SSL=1 \ + @ACE_TLS_CPPFLAGS@ + +server_SOURCES = \ + SSL-server.cpp \ + SSL-client-simple.h \ + SSL-client.h \ + SSL-server-fancy.h + +server_LDFLAGS = \ + @ACE_TLS_LDFLAGS@ + +server_LDADD = \ + $(ACE_BUILDDIR)/ace/SSL/libACE_SSL.la \ + $(ACE_BUILDDIR)/ace/libACE.la \ + @ACE_TLS_LIBS@ + +endif !BUILD_ACE_FOR_TAO +endif BUILD_SSL + +## Makefile.SSL_SAP_Server_Fancy.am + +if BUILD_SSL +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += server-fancy + +server_fancy_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -DACE_HAS_SSL=1 \ + @ACE_TLS_CPPFLAGS@ + +server_fancy_SOURCES = \ + SSL-server-fancy.cpp \ + SSL-server-fancy.h + +server_fancy_LDFLAGS = \ + @ACE_TLS_LDFLAGS@ + +server_fancy_LDADD = \ + $(ACE_BUILDDIR)/ace/SSL/libACE_SSL.la \ + $(ACE_BUILDDIR)/ace/libACE.la \ + @ACE_TLS_LIBS@ + +endif !BUILD_ACE_FOR_TAO +endif BUILD_SSL + +## Makefile.SSL_SAP_Server_Poll.am + +if BUILD_SSL +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += server-poll + +server_poll_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -DACE_HAS_SSL=1 \ + @ACE_TLS_CPPFLAGS@ + +server_poll_SOURCES = \ + SSL-server-poll.cpp \ + SSL-client-simple.h \ + SSL-client.h \ + SSL-server-fancy.h + +server_poll_LDFLAGS = \ + @ACE_TLS_LDFLAGS@ + +server_poll_LDADD = \ + $(ACE_BUILDDIR)/ace/SSL/libACE_SSL.la \ + $(ACE_BUILDDIR)/ace/libACE.la \ + @ACE_TLS_LIBS@ + +endif !BUILD_ACE_FOR_TAO +endif BUILD_SSL + +## Makefile.SSL_SAP_Server_Simple.am + +if BUILD_SSL +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += server-simple + +server_simple_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) \ + -DACE_HAS_SSL=1 \ + @ACE_TLS_CPPFLAGS@ + +server_simple_SOURCES = \ + SSL-server-simple.cpp \ + SSL-client-simple.h \ + SSL-client.h \ + SSL-server-fancy.h + +server_simple_LDFLAGS = \ + @ACE_TLS_LDFLAGS@ + +server_simple_LDADD = \ + $(ACE_BUILDDIR)/ace/SSL/libACE_SSL.la \ + $(ACE_BUILDDIR)/ace/libACE.la \ + @ACE_TLS_LIBS@ + +endif !BUILD_ACE_FOR_TAO +endif BUILD_SSL + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/IPC_SAP/SSL_SAP/README b/ACE/examples/IPC_SAP/SSL_SAP/README new file mode 100644 index 00000000000..43f4640e75a --- /dev/null +++ b/ACE/examples/IPC_SAP/SSL_SAP/README @@ -0,0 +1,17 @@ +# $Id$ + +This directory contains groups of client and server test programs that +exercise the various C++ wrappers for SSL sockets. In general, the +test programs do more or less the same thing -- the client establishes +a connection with the server and then transfers data to the server, +which keeps printing the data until EOF is reached (e.g., user types +^D). + +Unless noted differently, the server is implemented as an "iterative +server," i.e., it only deals with one client at a time. The following +describes each set of tests in more detail: + + . SSL-{client,server}.cpp -- This test allows you to test + oneway and twoway socket communication latency and + throughput over SSL between two processes on the same + machine or on different machines. diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-client-simple.cpp b/ACE/examples/IPC_SAP/SSL_SAP/SSL-client-simple.cpp new file mode 100644 index 00000000000..42bdd76d4c8 --- /dev/null +++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-client-simple.cpp @@ -0,0 +1,379 @@ +// $Id$ + +// This tests the features of the <ACE_SSL_SOCK_Connector> and +// <ACE_SSL_SOCK_Stream> classes. In addition, it can be used to test the +// oneway and twoway latency and throughput at the socket-level. This +// is useful as a baseline to compare against ORB-level performance +// for the same types of data. + +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_unistd.h" +#include "ace/INET_Addr.h" +#include "ace/Log_Msg.h" +#include "ace/Singleton.h" +#include "ace/Get_Opt.h" +#include "ace/High_Res_Timer.h" +#include "ace/Null_Mutex.h" + +#include "ace/SSL/SSL_SOCK_Connector.h" + +#include "SSL-client-simple.h" + +ACE_RCSID (SSL_SAP, + SSL_client_simple, + "$Id$") + + +Options::Options (void) + : host_ (ACE_DEFAULT_SERVER_HOST), + port_ (ACE_DEFAULT_SERVER_PORT), + sleep_time_ (0, 0), // By default, don't sleep between calls. + message_len_ (0), + message_buf_ (0), + io_source_ (ACE_INVALID_HANDLE), // Defaults to using the generator. + iterations_ (10000), + oneway_ (1) // Make oneway calls the default. +{ + ACE_OS::strcpy (quit_string_, "q"); +} + +Options::~Options (void) +{ + delete [] this->message_buf_; +} + +// Options Singleton. +typedef ACE_Singleton<Options, ACE_Null_Mutex> OPTIONS; + +int +Options::init (void) +{ + // Check for default case. + if (this->message_len_ == 0) + this->message_len_ = ACE_OS::strlen ("TAO"); + + this->message_len_ += sizeof (ACE_UINT32); + + ACE_NEW_RETURN (this->message_buf_, + char[this->message_len_], + -1); + + // Copy the length into the beginning of the message. + ACE_UINT32 length = ntohl (this->message_len_); + ACE_OS::memcpy ((void *) this->message_buf_, + (void *) &length, + sizeof length); + + ACE_OS::memset ((void *) (this->message_buf_ + sizeof (ACE_UINT32)), + 'a', + this->message_len_ - sizeof (ACE_UINT32)); + + return 0; +} + +size_t +Options::message_len (void) const +{ + return this->message_len_; +} + +const void * +Options::message_buf (void) const +{ + return this->message_buf_; +} + +ssize_t +Options::read (void *buf, size_t len, size_t &iteration) +{ + ACE_UNUSED_ARG (len); + + if (this->io_source_ == ACE_STDIN) + return ACE_OS::read (ACE_STDIN, buf, len); + else if (iteration >= this->iterations_) + return 0; + else + { + ACE_OS::memcpy (buf, + this->message_buf (), + len); + iteration++; + return len; + } +} + +int +Options::parse_args (int argc, ACE_TCHAR *argv[]) +{ + //FUZZ: disable check_for_lack_ACE_OS + ACE_Get_Opt getopt (argc, argv, ACE_TEXT ("2h:i:m:p:q:sT:"), 1); + + for (int c; (c = getopt ()) != -1; ) + //FUZZ: enable check_for_lack_ACE_OS + switch (c) + { + case '2': // Disable the oneway client. + this->oneway_ = 0; + break; + case 'h': + this->host_ = getopt.opt_arg (); + break; + case 'i': + this->iterations_ = ACE_OS::atoi (getopt.opt_arg ()); + break; + case 'm': + this->message_len_ = ACE_OS::atoi (getopt.opt_arg ()); + break; + case 'p': + this->port_ = ACE_OS::atoi (getopt.opt_arg ()); + break; + case 'q': + ACE_OS::strncpy (this->quit_string_, + ACE_TEXT_ALWAYS_CHAR (getopt.opt_arg ()), + QUIT_STRING_SIZE); + break; + case 's': + this->io_source_ = ACE_STDIN; + break; + case 'T': + this->sleep_time_.set (0, ACE_OS::atoi (getopt.opt_arg ())); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) usage: %n [-2] [-h <host>] ") + ACE_TEXT ("[-i iterations] [-m message-size] ") + ACE_TEXT ("[-p <port>] [-q <quit string>] ") + ACE_TEXT ("[-s] [-T <sleep_time>]\n")), + -1); + } + + return this->init (); +} + +u_short +Options::port (void) const +{ + return this->port_; +} + +const ACE_TCHAR * +Options::host (void) const +{ + return this->host_; +} + +const char * +Options::quit_string (void) const +{ + return this->quit_string_; +} + +const ACE_Time_Value & +Options::sleep_time (void) const +{ + return this->sleep_time_; +} + +char * +Options::shared_client_test (u_short port, + ACE_SSL_SOCK_Stream &cli_stream) +{ + ACE_INET_Addr remote_addr (port, this->host_); + + ACE_SSL_SOCK_Connector con; + + if (con.connect (cli_stream, + remote_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("connection failed")), + 0); + else + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) connected to %C at port %d\n"), + remote_addr.get_host_name (), + remote_addr.get_port_number ())); + + char *buf; + ACE_NEW_RETURN (buf, + char[this->message_len ()], + 0); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) waiting...\n"))); + + return buf; +} +// Static function entry point to the oneway client service. + +void +Options::oneway_client_test (void) +{ + ACE_SSL_SOCK_Stream cli_stream; + + // Add 1 to the port to trigger the oneway test! + char *request = this->shared_client_test (this->port () + 1, + cli_stream); + if (request == 0) + return; + + // This variable is allocated off the stack to obviate the need for + // locking. + size_t iteration = 0; + + // Keep track of return value. + int result = 0; + ACE_INT32 len = this->message_len (); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) starting oneway transmission\n"))); + + // Perform oneway transmission of data to server (correctly handles + // "incomplete writes"). + + for (ssize_t r_bytes; + (r_bytes = this->read (request, len, iteration)) > 0; + // Transmit at the proper rate. + ACE_OS::sleep (this->sleep_time ())) + if (ACE_OS::memcmp (request, + this->quit_string (), + ACE_OS::strlen (this->quit_string ())) == 0) + break; + else if (cli_stream.send_n (request, r_bytes) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("send_n"))); + result = -1; + break; + } + + // Close the connection. + cli_stream.close (); + + delete [] request; +} + +// Static function entry point to the twoway client service. + +void +Options::twoway_client_test (void) +{ + ACE_SSL_SOCK_Stream cli_stream; + + char *request = this->shared_client_test (this->port (), + cli_stream); + if (request == 0) + return; + + // This variable is allocated off the stack to obviate the need for + // locking. + size_t iteration = 0; + + // Keep track of return value. + int result = 0; + + // Timer business. + ACE_High_Res_Timer timer; + + ACE_INT32 len = this->message_len (); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) starting twoway transmission\n"))); + + // Perform twoway transmission of data to server (correctly handles + // "incomplete writes"). + + for (ssize_t r_bytes; + (r_bytes = this->read (request, len, iteration)) > 0; + // Transmit at the proper rate. + ACE_OS::sleep (this->sleep_time ())) + if (ACE_OS::memcmp (request, + this->quit_string (), + ACE_OS::strlen (this->quit_string ())) == 0) + break; + + // Transmit <request> to the server. + else + { + // Note that we use the incremental feature of the + // <ACE_High_Res_Timer> so that we don't get "charged" for the + // <ACE_OS::sleep> used to control the rate at which requests + // are sent. + timer.start_incr (); + + if (cli_stream.send_n (request, r_bytes) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("send_n"))); + result = -1; + break; + } + // Receive the reply from the server. Normally, it just sends + // back 24 bytes, which is typical for an IIOP reply. + else if (cli_stream.recv (request, r_bytes) <= 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("recv"))); + result = -1; + break; + } + + timer.stop_incr (); + } + + ACE_Time_Value tv; + + timer.elapsed_time_incr (tv); + double real_time = tv.sec () * ACE_ONE_SECOND_IN_USECS + tv.usec (); + double messages_per_sec = iteration * double (ACE_ONE_SECOND_IN_USECS) / real_time; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) messages = %d\n(%t) usec-per-message = %f\n(%t) messages-per-second = %0.00f\n"), + iteration, + real_time / double (iteration), + messages_per_sec < 0 ? 0 : messages_per_sec)); + + // Close the connection. + cli_stream.close (); + + delete [] request; +} + +void +Options::run (void) +{ + if (this->oneway_ == 0) + this->twoway_client_test (); + else + this->oneway_client_test (); +} + +static int +run_client (void) +{ + // Raise the socket handle limit to the maximum. + ACE::set_handle_limit (); + + OPTIONS::instance ()->run (); + + return 0; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + // Initialize the logger. + ACE_LOG_MSG->open (argv[0]); + + if (OPTIONS::instance ()->parse_args (argc, argv) == -1) + return -1; + + // Run the client + run_client (); + + return 0; +} + diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-client-simple.h b/ACE/examples/IPC_SAP/SSL_SAP/SSL-client-simple.h new file mode 100644 index 00000000000..4ec6b815a4c --- /dev/null +++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-client-simple.h @@ -0,0 +1,98 @@ +// -*- C++ -*- +// $Id$ + +// This file defines the Options class for SSL-client-simple. IBM C++ +// compiler's template auto-instantiator needs this in a separate file. + +#ifndef ACE_SSL_CLIENT_SIMPLE_H +#define ACE_SSL_CLIENT_SIMPLE_H + +#include "ace/SSL/SSL_SOCK_Stream.h" +#include "ace/Time_Value.h" + +class Options + // = TITLE + // Define the options for this test. +{ +public: + Options (void); + // Constructor. + + ~Options (void); + // Destructor. + + int parse_args (int argc, ACE_TCHAR *argv[]); + // Parse the command-line arguments. + + const ACE_Time_Value &sleep_time (void) const; + // Return the amount of time to sleep in order to implement the + // proper transmission rates. + + u_short port (void) const; + // Port of the server. + + const ACE_TCHAR *host (void) const; + // Host of the server. + + const char *quit_string (void) const; + // String that shuts down the client/server. + + ssize_t read (void *buf, size_t len, size_t &iterations); + // Read from the appropriate location. + + size_t message_len (void) const; + // Returns the length of the message to send. + + const void *message_buf (void) const; + // Returns a pointer to the message. + + void run (void); + // Run the test + +private: + int init (void); + // Initialize the message we're sending to the user and set up the + // barrier. + + char *shared_client_test (u_short port, + ACE_SSL_SOCK_Stream &cli_stream); + // Performs the shared behavior of the oneway and twoway client + // tests. + + void twoway_client_test (void); + // Performs the twoway test. + + void oneway_client_test (void); + // Performs the oneway test. + + const ACE_TCHAR *host_; + // Host of the server. + + u_short port_; + // Port of the server. + + ACE_Time_Value sleep_time_; + // Sleep_Time value. + + enum {QUIT_STRING_SIZE = 128}; + char quit_string_[QUIT_STRING_SIZE]; + // String that shuts down the client/server. + + size_t message_len_; + // Size of the message we send to the server. + + char *message_buf_; + // Pointer to the message we send to the server. + + ACE_HANDLE io_source_; + // Are we reading I/O from ACE_STDIN or from our generator? + + size_t iterations_; + // Number of iterations. + + char oneway_; + // Are we running oneway or twoway? + +}; + +#endif /* ACE_SSL_CLIENT_SIMPLE_H */ diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-client.cpp b/ACE/examples/IPC_SAP/SSL_SAP/SSL-client.cpp new file mode 100644 index 00000000000..829f8a5fe5e --- /dev/null +++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-client.cpp @@ -0,0 +1,420 @@ +// $Id$ + +// This tests the features of the <ACE_SSL_SOCK_Connector> and +// <ACE_SSL_SOCK_Stream> classes. In addition, it can be used to test the +// oneway and twoway latency and throughput at the socket-level. This +// is useful as a baseline to compare against ORB-level performance +// for the same types of data. + +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_unistd.h" +#include "ace/INET_Addr.h" +#include "ace/Thread_Manager.h" +#include "ace/Singleton.h" +#include "ace/Get_Opt.h" +#include "ace/High_Res_Timer.h" + +#include "ace/SSL/SSL_SOCK_Connector.h" + +#include "SSL-client.h" + +ACE_RCSID(SSL_SAP, SSL_client, "$Id$") + +Options::Options (void) + : host_ (ACE_DEFAULT_SERVER_HOST), + port_ (ACE_DEFAULT_SERVER_PORT), + sleep_time_ (0, 0), // By default, don't sleep between calls. + threads_ (10), + message_len_ (0), + message_buf_ (0), + io_source_ (ACE_INVALID_HANDLE), // Defaults to using the generator. + iterations_ (10000), + oneway_ (1) // Make oneway calls the default. +#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) + , barrier_ (0) +#endif /* ACE_MT_SAFE */ +{ + ACE_OS::strcpy (quit_string_, "q"); +} + +Options::~Options (void) +{ + ACE_MT (delete this->barrier_); + delete [] this->message_buf_; +} + +// Options Singleton. +typedef ACE_Singleton<Options, ACE_SYNCH_RECURSIVE_MUTEX> OPTIONS; + +int +Options::init (void) +{ + // Check for default case. + if (this->message_len_ == 0) + this->message_len_ = ACE_OS::strlen ("TAO"); + + this->message_len_ += sizeof (ACE_UINT32); + + ACE_NEW_RETURN (this->message_buf_, + char[this->message_len_], + -1); + + // Copy the length into the beginning of the message. + ACE_UINT32 length = ntohl (this->message_len_); + ACE_OS::memcpy ((void *) this->message_buf_, + (void *) &length, + sizeof length); + + ACE_OS::memset ((void *) (this->message_buf_ + sizeof (ACE_UINT32)), + 'a', + this->message_len_ - sizeof (ACE_UINT32)); + + // Allocate the barrier with the correct count. + ACE_MT (ACE_NEW_RETURN (this->barrier_, + ACE_Barrier (this->threads_), + -1)); + return 0; +} + +size_t +Options::message_len (void) const +{ + return this->message_len_; +} + +const void * +Options::message_buf (void) const +{ + return this->message_buf_; +} + +ssize_t +Options::read (void *buf, size_t len, size_t &iteration) +{ + ACE_UNUSED_ARG (len); + + if (this->io_source_ == ACE_STDIN) + return ACE_OS::read (ACE_STDIN, buf, len); + else if (iteration >= this->iterations_) + return 0; + else + { + ACE_OS::memcpy (buf, + this->message_buf (), + len); + iteration++; + return len; + } +} + +int +Options::parse_args (int argc, ACE_TCHAR *argv[]) +{ + //FUZZ: disable check_for_lack_ACE_OS + ACE_Get_Opt getopt (argc, argv, ACE_TEXT ("2h:i:m:p:q:st:T:"), 1); + + for (int c; (c = getopt ()) != -1; ) + //FUZZ: enable check_for_lack_ACE_OS + switch (c) + { + case '2': // Disable the oneway client. + this->oneway_ = 0; + break; + case 'h': + this->host_ = getopt.opt_arg (); + break; + case 'i': + this->iterations_ = ACE_OS::atoi (getopt.opt_arg ()); + break; + case 'm': + this->message_len_ = ACE_OS::atoi (getopt.opt_arg ()); + break; + case 'p': + this->port_ = ACE_OS::atoi (getopt.opt_arg ()); + break; + case 'q': + ACE_OS::strncpy (this->quit_string_, + ACE_TEXT_ALWAYS_CHAR (getopt.opt_arg ()), + QUIT_STRING_SIZE); + break; + case 's': + this->io_source_ = ACE_STDIN; + break; + case 't': + this->threads_ = (size_t) ACE_OS::atoi (getopt.opt_arg ()); + break; + case 'T': + this->sleep_time_.set (0, ACE_OS::atoi (getopt.opt_arg ())); + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) usage: %n [-2] [-h <host>] ") + ACE_TEXT ("[-i iterations] [-m message-size] ") + ACE_TEXT ("[-p <port>] [-q <quit string>] ") + ACE_TEXT ("[-s] [-t <threads>] [-T <sleep_time>]\n")), + -1); + } + + return this->init (); +} + +u_short +Options::port (void) const +{ + return this->port_; +} + +const ACE_TCHAR * +Options::host (void) const +{ + return this->host_; +} + +const char * +Options::quit_string (void) const +{ + return this->quit_string_; +} + +size_t +Options::threads (void) const +{ + return this->threads_; +} + +const ACE_Time_Value & +Options::sleep_time (void) const +{ + return this->sleep_time_; +} + +char * +Options::shared_client_test (u_short port, + ACE_SSL_SOCK_Stream &cli_stream) +{ + ACE_INET_Addr remote_addr (port, this->host_); + + ACE_SSL_SOCK_Connector con; + + if (con.connect (cli_stream, + remote_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("connection failed")), + 0); + else + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) connected to %C at port %d\n"), + remote_addr.get_host_name (), + remote_addr.get_port_number ())); + + // Allocate the transmit buffer. + char *buf; + ACE_NEW_RETURN (buf, + char[this->message_len ()], + 0); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) waiting...\n"))); + + // Wait for all other threads to finish initialization. + ACE_MT (this->barrier_->wait ()); + return buf; +} +// Static function entry point to the oneway client service. + +void * +Options::oneway_client_test (void *) +{ + Options *options = OPTIONS::instance (); + ACE_SSL_SOCK_Stream cli_stream; + + // Add 1 to the port to trigger the oneway test! + char *request = options->shared_client_test (options->port () + 1, + cli_stream); + if (request == 0) + return 0; + + // This variable is allocated off the stack to obviate the need for + // locking. + size_t iteration = 0; + + // Keep track of return value. + size_t result = 0; + ACE_INT32 len = options->message_len (); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) starting oneway transmission\n"))); + + // Perform oneway transmission of data to server (correctly handles + // "incomplete writes"). + + for (ssize_t r_bytes; + (r_bytes = options->read (request, len, iteration)) > 0; + // Transmit at the proper rate. + ACE_OS::sleep (options->sleep_time ())) + if (ACE_OS::memcmp (request, + options->quit_string (), + ACE_OS::strlen (options->quit_string ())) == 0) + break; + else if (cli_stream.send_n (request, r_bytes) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("send_n"))); + result = size_t (-1); + break; + } + + // Close the connection. + cli_stream.close (); + + delete [] request; + return (void *) result; +} + +// Static function entry point to the twoway client service. + +void * +Options::twoway_client_test (void *) +{ + Options *options = OPTIONS::instance (); + + ACE_SSL_SOCK_Stream cli_stream; + + char *request = options->shared_client_test (options->port (), + cli_stream); + if (request == 0) + return 0; + + // This variable is allocated off the stack to obviate the need for + // locking. + size_t iteration = 0; + + // Keep track of return value. + size_t result = 0; + + // Timer business. + ACE_High_Res_Timer timer; + + ACE_INT32 len = options->message_len (); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) starting twoway transmission\n"))); + + // Perform twoway transmission of data to server (correctly handles + // "incomplete writes"). + + for (ssize_t r_bytes; + (r_bytes = options->read (request, len, iteration)) > 0; + // Transmit at the proper rate. + ACE_OS::sleep (options->sleep_time ())) + if (ACE_OS::memcmp (request, + options->quit_string (), + ACE_OS::strlen (options->quit_string ())) == 0) + break; + + // Transmit <request> to the server. + else + { + // Note that we use the incremental feature of the + // <ACE_High_Res_Timer> so that we don't get "charged" for the + // <ACE_OS::sleep> used to control the rate at which requests + // are sent. + timer.start_incr (); + + if (cli_stream.send_n (request, r_bytes) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("send_n"))); + result = size_t (-1); + break; + } + // Receive the reply from the server. Normally, it just sends + // back 24 bytes, which is typical for an IIOP reply. + else if (cli_stream.recv (request, r_bytes) <= 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("recv"))); + result = size_t (-1); + break; + } + + timer.stop_incr (); + } + + ACE_Time_Value tv; + + timer.elapsed_time_incr (tv); + double real_time = tv.sec () * ACE_ONE_SECOND_IN_USECS + tv.usec (); + double messages_per_sec = + iteration * double (ACE_ONE_SECOND_IN_USECS) / real_time; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%t) messages = %d\n") + ACE_TEXT ("(%t) usec-per-message = %f\n") + ACE_TEXT ("(%t) messages-per-second = %0.00f\n"), + iteration, + real_time / double (iteration), + messages_per_sec < 0 ? 0 : messages_per_sec)); + + // Close the connection. + cli_stream.close (); + + delete [] request; + return (void *) result; +} + +ACE_THR_FUNC +Options::thr_func (void) +{ + if (this->oneway_ == 0) + return ACE_THR_FUNC (&Options::twoway_client_test); + else + return ACE_THR_FUNC (&Options::oneway_client_test); +} + +static int +run_client (void) +{ + // Raise the socket handle limit to the maximum. + ACE::set_handle_limit (); + +#if defined (ACE_HAS_THREADS) + if (ACE_Thread_Manager::instance ()->spawn_n ( + OPTIONS::instance ()->threads (), + OPTIONS::instance ()->thr_func ()) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("spawn_n")), + 1); + else + ACE_Thread_Manager::instance ()->wait (); +#else + *(OPTIONS::instance ()->thr_func) (); +#endif /* ACE_HAS_THREADS */ + return 0; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_SSL_Context *context = ACE_SSL_Context::instance (); + + context->certificate ("./dummy.pem", SSL_FILETYPE_PEM); + context->private_key ("./key.pem", SSL_FILETYPE_PEM); + + // Initialize the logger. + ACE_LOG_MSG->open (argv[0]); + + if (OPTIONS::instance ()->parse_args (argc, argv) == -1) + return -1; + + // Run the client + run_client (); + + return 0; +} + diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-client.h b/ACE/examples/IPC_SAP/SSL_SAP/SSL-client.h new file mode 100644 index 00000000000..af081004368 --- /dev/null +++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-client.h @@ -0,0 +1,111 @@ +// -*- C++ -*- +// $Id$ + +// This file defines the Options class for SSL-client. IBM C++ compiler'd +// template auto-instantiator needs this in a separate file. + +#ifndef __ACE_SSL_CLIENT_H +#define __ACE_SSL_CLIENT_H + +#include "ace/Barrier.h" +#include "ace/Time_Value.h" + +#include "ace/SSL/SSL_SOCK_Stream.h" + +class Options + // = TITLE + // Define the options for this test. +{ +public: + Options (void); + // Constructor. + + ~Options (void); + // Destructor. + + int parse_args (int argc, ACE_TCHAR *argv[]); + // Parse the command-line arguments. + + const ACE_Time_Value &sleep_time (void) const; + // Return the amount of time to sleep in order to implement the + // proper transmission rates. + + u_short port (void) const; + // Port of the server. + + const ACE_TCHAR *host (void) const; + // Host of the server. + + size_t threads (void) const; + // Number of threads. + + const char *quit_string (void) const; + // String that shuts down the client/server. + + ssize_t read (void *buf, size_t len, size_t &iterations); + // Read from the appropriate location. + + size_t message_len (void) const; + // Returns the length of the message to send. + + const void *message_buf (void) const; + // Returns a pointer to the message. + + ACE_THR_FUNC thr_func (void); + // Returns a pointer to the entry point into the thread that runs + // the client test function. + +private: + int init (void); + // Initialize the message we're sending to the user and set up the + // barrier. + + char *shared_client_test (u_short port, + ACE_SSL_SOCK_Stream &cli_stream); + // Performs the shared behavior of the oneway and twoway client + // tests. + + static void *twoway_client_test (void *); + // Performs the twoway test. + + static void *oneway_client_test (void *); + // Performs the oneway test. + + const ACE_TCHAR *host_; + // Host of the server. + + u_short port_; + // Port of the server. + + ACE_Time_Value sleep_time_; + // Sleep_Time value. + + size_t threads_; + // Number of threads. + + enum {QUIT_STRING_SIZE = 128}; + char quit_string_[QUIT_STRING_SIZE]; + // String that shuts down the client/server. + + size_t message_len_; + // Size of the message we send to the server. + + char *message_buf_; + // Pointer to the message we send to the server. + + ACE_HANDLE io_source_; + // Are we reading I/O from ACE_STDIN or from our generator? + + size_t iterations_; + // Number of iterations. + + char oneway_; + // Are we running oneway or twoway? + + // Please leave the ; inside the parenthesis to avoid Green Hills + // (and probably other) compiler warning about extra ;. + ACE_MT (ACE_Barrier *barrier_;) + // Barrier used to synchronize the start of all the threads. +}; + +#endif /* __ACE_SSL_CLIENT_H */ diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-fancy.cpp b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-fancy.cpp new file mode 100644 index 00000000000..1ad03125e9d --- /dev/null +++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-fancy.cpp @@ -0,0 +1,610 @@ +// $Id$ + +// This example tests the features of the <ACE_SSL_SOCK_Acceptor>, +// <ACE_SSL_SOCK_Stream>, and <ACE_Svc_Handler> classes. If the platform +// supports threads it uses a thread-per-connection concurrency model. +// Otherwise, it uses a single-threaded iterative server model. + +#include "ace/Svc_Handler.h" +#include "ace/Singleton.h" +#include "ace/Profile_Timer.h" +#include "ace/Get_Opt.h" +#include "ace/OS_NS_sys_select.h" + +#include "ace/SSL/SSL_SOCK_Acceptor.h" + +#include "SSL-server-fancy.h" + +ACE_RCSID (SSL_SAP, + SSL_server_fancy, + "$Id$") + +// Forward declaration. +class Handler; + +class Handler_Factory +{ + // = TITLE + // Creates the oneway or twoway handlers. +public: + Handler_Factory (void); + // Constructor. + + ~Handler_Factory (void); + // Destructor. + + int handle_events (void); + // Run the main event loop. + +private: + int init_acceptors (void); + // Initialize the acceptors. + + int create_handler (ACE_SSL_SOCK_Acceptor &acceptor, + Handler *(*handler_factory) (ACE_SSL_SOCK_Stream *), + const char *handler_type); + // Factory that creates the right kind of <Handler>. + + // = Factory functions. + + static Handler *make_twoway_handler (ACE_SSL_SOCK_Stream *); + // Create a twoway handler. + + static Handler *make_oneway_handler (ACE_SSL_SOCK_Stream *); + // Create a oneway handler. + + ACE_SSL_SOCK_Acceptor twoway_acceptor_; + // Twoway acceptor factory. + + ACE_SSL_SOCK_Acceptor oneway_acceptor_; + // Oneway acceptor factory. +}; + +class Handler : public ACE_Svc_Handler<ACE_SSL_SOCK_STREAM, ACE_NULL_SYNCH> +{ + // = TITLE + // Base class for the oneway and twoway handlers. + + friend class Handler_Factory; + // The factory has special permission. (to access svc ()). + +public: + //FUZZ: disable check_for_lack_ACE_OS + virtual int open (void * = 0); + // Generic initialization method. + + virtual int close (u_long); + // Close down and delete this. + //FUZZ: enable check_for_lack_ACE_OS + +protected: + + Handler (ACE_SSL_SOCK_Stream *ssl_stream); + // Constructor. + + int parse_header_and_allocate_buffer (char *&buf, + ACE_INT32 *len); + // Implement the generic code that's called from any of the subclass + // <run> methods to get the header and the buffer to read the data. + // This method factors out common code. + + virtual int run (void) = 0; + // Hook method called by the <svc> template method to do the actual + // protocol. Must be overridden by the subclass. + + virtual int svc (void); + // Template method entry point into the handler task. + + virtual void print_results (void); + // Print the results. + + size_t total_bytes_; + // Total number of bytes received. + + size_t message_count_; + // Number of messages received. + + ACE_Profile_Timer timer_; + // Keeps track of how much time we're using. + + ACE_SSL_SOCK_Stream *ssl_stream_; + //keep state information for a ssl_stream. +}; + +class Twoway_Handler : public Handler +{ + // = TITLE + // Performs the twoway protocol. +public: + + Twoway_Handler (ACE_SSL_SOCK_Stream *ssl_stream); + // Constructor. + +private: + + virtual int run (void); + // Template Method hook called by <svc>. + +}; + +class Oneway_Handler : public Handler +{ + // = TITLE +public: + Oneway_Handler (ACE_SSL_SOCK_Stream *ssl_stream); + // Constructor. + +private: + virtual int run (void); + // Template Method hook called by <svc>. + + virtual void print_results (void); + // Print the results. +}; + +u_short +Options::port (void) const +{ + return this->port_; +} + +int +Options::verbose (void) const +{ + return this->verbose_; +} + +int +Options::reply_message_len (void) const +{ + return this->reply_message_len_; +} + +Options::~Options (void) +{ +} + +Options::Options (void) + : verbose_ (0), + port_ (ACE_DEFAULT_SERVER_PORT), + reply_message_len_ (24) // Default to the approximate size of an + // GIOP reply message. +{ +} + +int +Options::parse_args (int argc, ACE_TCHAR *argv[]) +{ + //FUZZ: disable check_for_lack_ACE_OS + ACE_Get_Opt getopt (argc, argv, ACE_TEXT ("p:r:v"), 1); + + for (int c; (c = getopt ()) != -1; ) + //FUZZ: enable check_for_lack_ACE_OS + switch (c) + { + case 'p': + this->port_ = ACE_OS::atoi (getopt.opt_arg ()); + break; + case 'r': + this->reply_message_len_ = ACE_OS::atoi (getopt.opt_arg ()); + break; + case 'v': + this->verbose_ = 1; + break; + default: + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) usage: %n [-p <port>] [-v]")), + -1); + } + + return 0; +} + +// Options Singleton. +typedef ACE_Singleton<Options, ACE_SYNCH_RECURSIVE_MUTEX> OPTIONS; + +Handler::Handler (ACE_SSL_SOCK_Stream *ssl_stream) + : total_bytes_ (0), + message_count_ (0), + ssl_stream_ (ssl_stream) + +{ +} + +int +Handler::open (void *) +{ + ACE_INET_Addr cli_addr; + + // Make sure we're not in non-blocking mode. + if (this->ssl_stream_-> disable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("disable")), + 0); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) client %C connected from %d \n"), + cli_addr.get_host_name (), + cli_addr.get_port_number ())); + + return 0; +} + +int +Handler::close (u_long) +{ + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) closing down %@\n"), + this)); + + delete this->ssl_stream_; + delete this; + + return 0; +} + +int +Handler::svc (void) +{ + // Timer logic. + this->timer_.start (); + + // Invoke the hook method to run the specific test. + int result = this->run (); + + this->timer_.stop (); + + this->print_results (); + + return result; +} + +int +Handler::parse_header_and_allocate_buffer (char *&request, + ACE_INT32 *len) +{ + ssize_t result = this->ssl_stream_ -> recv_n ((void *) len, + sizeof (ACE_INT32)); + if (result == 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) connected closed\n"))); + return -1; + } + else if (result == -1 || result != sizeof (ACE_INT32)) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("recv_n failed")), + -1); + else + { + *len = ntohl (*len); + ACE_NEW_RETURN (request, + char[*len], + -1); + } + + return 0; +} + +void +Handler::print_results (void) +{ +} + +Twoway_Handler::Twoway_Handler (ACE_SSL_SOCK_Stream* ssl_stream) + : Handler (ssl_stream) +{ +} + +// Function entry point into the twoway server task. + +int +Twoway_Handler::run (void) +{ + // Read data from client (terminate on error). + + char *request = 0; + + for (;;) + { + ACE_INT32 len = 0; + + if (parse_header_and_allocate_buffer (request, + &len) == -1) + return -1; + + // Subtract off the sizeof the length prefix. + ssize_t r_bytes = + this->ssl_stream_ -> recv_n (request, + len - sizeof (ACE_UINT32)); + + if (r_bytes == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("recv"))); + break; + } + else if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) reached end of input, connection ") + ACE_TEXT ("closed by client\n"))); + break; + } + else if (OPTIONS::instance ()->verbose () + && ACE::write_n (ACE_STDOUT, + request, + r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::write_n"))); + else + { + ssize_t s_bytes = + (ssize_t) OPTIONS::instance ()->reply_message_len (); + + // Don't try to send more than is in the request buffer! + if (s_bytes > r_bytes) + s_bytes = r_bytes; + + if (this->ssl_stream_ -> send_n (request, + s_bytes) != s_bytes) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("send_n"))); + } + this->total_bytes_ += size_t (r_bytes); + this->message_count_++; + + delete [] request; + request = 0; + } + + delete [] request; + return 0; +} + +Oneway_Handler::Oneway_Handler (ACE_SSL_SOCK_Stream *ssl_stream) + : Handler (ssl_stream) +{ +} + +void +Oneway_Handler::print_results (void) +{ + ACE_Profile_Timer::ACE_Elapsed_Time et; + this->timer_.elapsed_time (et); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\t\treal time = %f secs \n\t\tuser time = %f secs \n\t\tsystem time = %f secs\n"), + et.real_time, + et.user_time, + et.system_time)); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\t\tmessages = %d\n\t\ttotal bytes = %d\n\t\tmbits/sec = %f\n\t\tusec-per-message = %f\n"), + this->message_count_, + this->total_bytes_, + (((double) this->total_bytes_ * 8) / et.real_time) / (double) (1024 * 1024), + ((et.user_time + et.system_time) / (double) this->message_count_) * ACE_ONE_SECOND_IN_USECS)); +} + +// Function entry point into the oneway server task. + +int +Oneway_Handler::run (void) +{ + // Read data from client (terminate on error). + + char *request = 0; + + for (;;) + { + ACE_INT32 len = 0; + + if (parse_header_and_allocate_buffer (request, + &len) == -1) + return -1; + + // Subtract off the sizeof the length prefix. + ssize_t r_bytes = + this->ssl_stream_ -> recv_n (request, + len - sizeof (ACE_UINT32)); + + if (r_bytes == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("recv"))); + break; + } + else if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) reached end of input, connection ") + ACE_TEXT ("closed by client\n"))); + break; + } + else if (OPTIONS::instance ()->verbose () + && ACE::write_n (ACE_STDOUT, + request, + r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("ACE::write_n"))); + + this->total_bytes_ += size_t (r_bytes); + this->message_count_++; + delete [] request; + request = 0; + } + + delete [] request; + return 0; +} + +// Create a twoway handler. + +Handler * +Handler_Factory::make_twoway_handler (ACE_SSL_SOCK_Stream *ssl_stream) +{ + return new Twoway_Handler (ssl_stream); +} + +// Create a oneway handler. + +Handler * +Handler_Factory::make_oneway_handler (ACE_SSL_SOCK_Stream *ssl_stream) + +{ + return new Oneway_Handler (ssl_stream); +} + +int +Handler_Factory::init_acceptors (void) +{ + // Create the oneway and twoway server addresses. + ACE_INET_Addr twoway_server_addr (OPTIONS::instance ()->port ()); + ACE_INET_Addr oneway_server_addr (OPTIONS::instance ()->port () + 1); + + // Create acceptors, reuse the address. + if (this->twoway_acceptor_.open (twoway_server_addr, 1) == -1 + || this->oneway_acceptor_.open (oneway_server_addr, 1) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("open")), + -1); + else if (this->twoway_acceptor_.get_local_addr (twoway_server_addr) == -1 + || this->oneway_acceptor_.get_local_addr (oneway_server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("get_local_addr")), + -1); + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) starting twoway server at port %d and oneway server at port %d\n"), + twoway_server_addr.get_port_number (), + oneway_server_addr.get_port_number ())); + return 0; +} + +int +Handler_Factory::create_handler ( + ACE_SSL_SOCK_Acceptor &acceptor, + Handler * (*handler_factory) (ACE_SSL_SOCK_Stream* ), + const char *handler_type) +{ + ACE_SSL_SOCK_Stream* new_stream; + + ACE_NEW_RETURN (new_stream, ACE_SSL_SOCK_Stream, -1); + + if (acceptor.accept (*new_stream) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("accept")), + -1); + + Handler *handler; + + ACE_ALLOCATOR_RETURN (handler, + (*handler_factory) (new_stream), + -1); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) spawning %s handler\n"), + handler_type)); + + if (handler->open () == -1) + return -1; + +#if defined (ACE_MT_SAFE) + // Spawn a new thread and run the new connection in that thread of + // control using the <server> function as the entry point. + return handler->activate (); +#else + handler->svc (); + handler->close (0); + return 0; +#endif /* ACE_HAS_THREADS */ +} + +Handler_Factory::Handler_Factory (void) +{ +} + +Handler_Factory::~Handler_Factory (void) +{ + this->twoway_acceptor_.close (); + this->oneway_acceptor_.close (); +} + +// Run the main event loop. + +int +Handler_Factory::handle_events (void) +{ + if (this->init_acceptors () == -1) + return -1; + + fd_set handles; + + FD_ZERO (&handles); + FD_SET ((ACE_SOCKET) this->twoway_acceptor_.get_handle (), &handles); + FD_SET ((ACE_SOCKET) this->oneway_acceptor_.get_handle (), &handles); + + // Performs the iterative server activities. + + for (;;) + { + ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT); + fd_set temp = handles; + + int result = + ACE_OS::select (int (this->oneway_acceptor_.get_handle ()) + 1, + (fd_set *) &temp, + 0, + 0, + timeout); + if (result == -1) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) %p\n"), + ACE_TEXT ("select"))); + else if (result == 0 && OPTIONS::instance ()->verbose ()) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) select timed out\n"))); + else + { + if (FD_ISSET (this->twoway_acceptor_.get_handle (), + &temp)) + this->create_handler (this->twoway_acceptor_, + &Handler_Factory::make_twoway_handler, + "twoway"); + if (FD_ISSET (this->oneway_acceptor_.get_handle (), + &temp)) + this->create_handler (this->oneway_acceptor_, + &Handler_Factory::make_oneway_handler, + "oneway"); + } + } + + ACE_NOTREACHED (return 0;) +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + + ACE_SSL_Context *context = ACE_SSL_Context::instance (); + + context->certificate ("./dummy.pem", SSL_FILETYPE_PEM); + context->private_key ("./key.pem", SSL_FILETYPE_PEM); + + OPTIONS::instance ()->parse_args (argc, argv); + + Handler_Factory server; + + return server.handle_events (); +} + diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-fancy.h b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-fancy.h new file mode 100644 index 00000000000..fed1b513f90 --- /dev/null +++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-fancy.h @@ -0,0 +1,44 @@ +// -*- C++ -*- +// $Id$ + +// This file defines the Options class for SSL-server-fancy. +// IBM C++ compiler'd template auto-instantiator needs this in a separate file. + +#ifndef __ACE_SSL_SERVER_FANCY_H +#define __ACE_SSL_SERVER_FANCY_H + +class Options + // = TITLE + // Define the options for this test. +{ +public: + Options (void); + // Constructor. + + ~Options (void); + // Destructor. + + int parse_args (int argc, ACE_TCHAR *argv[]); + // Parse the command-line arguments. + + int verbose (void) const; + // Are we running in verbose mode? + + u_short port (void) const; + // Port number that we are listening at. + + int reply_message_len (void) const; + // Size of the reply message. + +private: + int verbose_; + // Are we running in verbose mode? + + u_short port_; + // Port number we listen at. + + size_t reply_message_len_; + // Size of the reply message. +}; + +#endif /* __ACE_SSL_SERVER_FANCY_H */ diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-poll.cpp b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-poll.cpp new file mode 100644 index 00000000000..23a53a7e7c7 --- /dev/null +++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-poll.cpp @@ -0,0 +1,212 @@ +// $Id$ + +// IPC_SAP/poll server, which illustrates how to integrate the ACE +// SSL socket wrappers with the SVR4 <poll> system call to create a +// single-threaded concurrent server. This server program can be +// driven by the oneway test mode of SSL-client.cpp. + +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Time_Value.h" +#include "ace/SSL/SSL_SOCK_Acceptor.h" + +ACE_RCSID (SSL_SAP, + SSL_server_poll, + "$Id$") + +#if defined (ACE_HAS_POLL) + +#include "ace/SSL/SSL_SOCK_Stream.h" + +#include "ace/Log_Msg.h" +#include "ace/INET_Addr.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_poll.h" + + +// Should we be verbose? +static int verbose = 0; + +// Max number of open handles. +static const int MAX_HANDLES = 200; + +struct Buffer_Info +{ + void *buf_; + // Pointer to the buffer. + + size_t len_; + // Length of the buffer. +}; + +// Array of <pollfd>'s. +static struct pollfd poll_array[MAX_HANDLES]; + +// Array of <Buffer_Info>. +static Buffer_Info buffer_array[MAX_HANDLES]; + +static void +init_poll_array (void) +{ + int i; + + for (i = 0; i < MAX_HANDLES; i++) + { + poll_array[i].fd = ACE_INVALID_HANDLE; + poll_array[i].events = POLLIN; + } +} + +static int +init_buffer (size_t index) +{ + ACE_INT32 len; + + if (ACE::recv_n (poll_array[index].fd, + (void *) &len, + sizeof (ACE_INT32)) != sizeof (ACE_INT32)) + ACE_ERROR_RETURN ((LM_ERROR, + "(%P|%t) %p\n", + "recv_n failed"), + -1); + else + { + len = ntohl (len); + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reading messages of size %d from handle %d\n", + len, + poll_array[index].fd)); + + ACE_ALLOCATOR_RETURN (buffer_array[index].buf_, + ACE_OS::malloc (len), + -1); + buffer_array[index].len_ = len; + } + return 0; +} + +static void +handle_data (size_t &n_handles) +{ + // Handle pending logging messages first (s_handle + 1 is guaranteed + // to be lowest client descriptor). + + for (size_t index = 1; index < n_handles; index++) + { + if (ACE_BIT_ENABLED (poll_array[index].revents, POLLIN)) + { + // First time in, we need to initialize the buffer. + if (buffer_array[index].buf_ == 0 + && init_buffer (index) == -1) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) %p\n", + "init_buffer")); + continue; + } + + // Read data from client (terminate on error). + + ssize_t n = ACE::recv (poll_array[index].fd, + buffer_array[index].buf_, + buffer_array[index].len_); + // <recv> will not block in this case! + + if (n == -1) + ACE_ERROR ((LM_ERROR, + "%p\n", + "read failed")); + else if (n == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) closing oneway server at handle %d\n", + poll_array[index].fd)); + + // Handle client connection shutdown. + ACE_OS::close (poll_array[index].fd); + poll_array[index].fd = poll_array[--n_handles].fd; + + ACE_OS::free ((void *) buffer_array[index].buf_); + buffer_array[index].buf_ = 0; + buffer_array[index].len_ = 0; + } + else if (verbose) + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) %*s", + n, + buffer_array[index].buf_)); + } + } +} + +static void +handle_connections (ACE_SSL_SOCK_Acceptor &peer_acceptor, + size_t &n_handles) +{ + if (ACE_BIT_ENABLED (poll_array[0].revents, POLLIN)) + { + ACE_SSL_SOCK_Stream new_stream; + + ACE_INET_Addr client; + ACE_Time_Value nonblock (0, 0); + + // Handle all pending connection requests (note use of "polling" + // feature that doesn't block). + + while (ACE_OS::poll (poll_array, 1, nonblock) > 0) + if (peer_acceptor.accept (new_stream, &client) == -1) + ACE_OS::perror ("accept"); + else + { + const char *s = client.get_host_name (); + + ACE_ASSERT (s != 0); + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) client %s\n", + s)); + poll_array[n_handles++].fd = new_stream.get_handle (); + } + } +} + +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + u_short port = ACE_DEFAULT_SERVER_PORT + 1; + + // Create a server end-point. + ACE_INET_Addr addr (port); + ACE_SSL_SOCK_Acceptor peer_acceptor (addr); + + ACE_HANDLE s_handle = peer_acceptor.get_handle (); + + init_poll_array (); + + poll_array[0].fd = s_handle; + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) starting oneway server at port %d\n", + port)); + + for (size_t n_handles = 1;;) + { + // Wait for client I/O events (handle interrupts). + while (ACE_OS::poll (poll_array, n_handles) == -1 + && errno == EINTR) + continue; + + handle_data (n_handles); + handle_connections (peer_acceptor, n_handles); + } + + /* NOTREACHED */ + return 0; +} +#else +#include "ace/OS_NS_stdio.h" +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_OS::fprintf (stderr, "This feature is not supported\n"); + return 0; +} +#endif /* ACE_HAS_POLL */ diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-simple.cpp b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-simple.cpp new file mode 100644 index 00000000000..6be3ce47b9e --- /dev/null +++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-simple.cpp @@ -0,0 +1,366 @@ +// $Id$ + +// This example tests the features of the <ACE_SSL_SOCK_Acceptor>, +// <ACE_SSL_SOCK_Stream>, and <ACE_Svc_Handler> classes. + +#include "ace/Thread_Manager.h" +#include "ace/Handle_Set.h" +#include "ace/Profile_Timer.h" +#include "ace/OS_NS_sys_select.h" + +#include "ace/SSL/SSL_SOCK_Acceptor.h" + +ACE_RCSID(SSL_SAP, SSL_server_simple, "$Id$") + +// Are we running verbosely? +static int verbose = 1; + +// Function entry point into the twoway server task. + +int +twoway_server (ACE_SSL_SOCK_Stream &stream) +{ + ACE_INET_Addr cli_addr; + + // Make sure we're not in non-blocking mode. + if (stream.disable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "disable"), + 0); + else if (stream.get_remote_addr (cli_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "get_remote_addr"), + 0); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) client %s connected from %d\n", + cli_addr.get_host_name (), + cli_addr.get_port_number ())); + + size_t total_bytes = 0; + size_t message_count = 0; + + char *request = 0; + + // Read data from client (terminate on error). + + for (;;) + { + ACE_INT32 len; + + ssize_t r_bytes = stream.recv_n ((void *) &len, + sizeof (ACE_INT32)); + if (r_bytes == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "recv")); + break; + } + else if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reached end of input, connection closed by client\n")); + break; + } + else if (r_bytes != sizeof (ACE_INT32)) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) %p\n", + "recv_n failed")); + break; + } + else + { + len = ntohl (len); + ACE_NEW_RETURN (request, + char [len], + 0); + } + + // Subtract off the sizeof the length prefix. + r_bytes = stream.recv_n (request, + len - sizeof (ACE_UINT32)); + if (r_bytes == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "recv")); + break; + } + else if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reached end of input, connection closed by client\n")); + break; + } + else if (verbose + && ACE::write_n (ACE_STDOUT, + request, + r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, + "%p\n", + "ACE::write_n")); + else if (stream.send_n (request, + r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, + "%p\n", + "send_n")); + + total_bytes += size_t (r_bytes); + message_count++; + + delete [] request; + request = 0; + } + + // Close new endpoint (listening endpoint stays open). + stream.close (); + + delete [] request; + return 0; +} + +// Function entry point into the oneway server task. + +static int +oneway_server (ACE_SSL_SOCK_Stream &stream) +{ + ACE_INET_Addr cli_addr; + + // Make sure we're not in non-blocking mode. + if (stream.disable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "disable"), + 0); + else if (stream.get_remote_addr (cli_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "get_remote_addr"), + 0); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) client %s connected from %d\n", + cli_addr.get_host_name (), + cli_addr.get_port_number ())); + + // Timer business + ACE_Profile_Timer timer; + timer.start (); + + size_t total_bytes = 0; + size_t message_count = 0; + + char *request = 0; + + // Read data from client (terminate on error). + + for (;;) + { + ACE_INT32 len; + + ssize_t r_bytes = stream.recv_n ((void *) &len, + sizeof (ACE_INT32)); + if (r_bytes == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "recv")); + break; + } + else if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reached end of input, connection closed by client\n")); + break; + } + else if (r_bytes != sizeof (ACE_INT32)) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) %p\n", + "recv_n failed")); + break; + } + else + { + len = ntohl (len); + ACE_NEW_RETURN (request, + char [len], + 0); + } + + // Subtract off the sizeof the length prefix. + r_bytes = stream.recv_n (request, + len - sizeof (ACE_UINT32)); + + if (r_bytes == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "recv")); + break; + } + else if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reached end of input, connection closed by client\n")); + break; + } + else if (verbose + && ACE::write_n (ACE_STDOUT, request, r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, + "%p\n", + "ACE::write_n")); + + total_bytes += size_t (r_bytes); + message_count++; + + delete [] request; + request = 0; + } + + timer.stop (); + + ACE_Profile_Timer::ACE_Elapsed_Time et; + timer.elapsed_time (et); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\t\treal time = %f secs \n\t\tuser time = %f secs \n\t\tsystem time = %f secs\n"), + et.real_time, + et.user_time, + et.system_time)); + + double messages_per_sec = double (message_count) / et.real_time; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\t\tmessages = %d\n\t\ttotal bytes = %d\n\t\tmbits/sec = %f\n\t\tusec-per-message = %f\n\t\tmessages-per-second = %0.00f\n"), + message_count, + total_bytes, + (((double) total_bytes * 8) / et.real_time) / (double) (1024 * 1024), + (et.real_time / (double) message_count) * 1000000, + messages_per_sec < 0 ? 0 : messages_per_sec)); + + // Close new endpoint (listening endpoint stays open). + stream.close (); + + delete [] request; + return 0; +} + +static int +run_event_loop (u_short port) +{ + // Raise the socket handle limit to the maximum. + ACE::set_handle_limit (); + + // Create the oneway and twoway acceptors. + ACE_SSL_SOCK_Acceptor twoway_acceptor; + ACE_SSL_SOCK_Acceptor oneway_acceptor; + + // Create the oneway and twoway server addresses. + ACE_INET_Addr twoway_server_addr (port); + ACE_INET_Addr oneway_server_addr (port + 1); + + // Create acceptors, reuse the address. + if (twoway_acceptor.open (twoway_server_addr, 1) == -1 + || oneway_acceptor.open (oneway_server_addr, 1) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "open"), + 1); + else if (twoway_acceptor.get_local_addr (twoway_server_addr) == -1 + || oneway_acceptor.get_local_addr (oneway_server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "get_local_addr"), + 1); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) starting twoway server at port %d and oneway server at port %d\n", + twoway_server_addr.get_port_number (), + oneway_server_addr.get_port_number ())); + + // Keep these objects out here to prevent excessive constructor + // calls within the loop. + ACE_SSL_SOCK_Stream new_stream; + + ACE_Handle_Set handle_set; + handle_set.set_bit (twoway_acceptor.get_handle ()); + handle_set.set_bit (oneway_acceptor.get_handle ()); + + // Performs the iterative server activities. + + for (;;) + { + ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT); + ACE_Handle_Set temp = handle_set; + + int maxfd = int(oneway_acceptor.get_handle ()); + if (maxfd < int(twoway_acceptor.get_handle ())) + maxfd = int(twoway_acceptor.get_handle ()); + int result = ACE_OS::select (maxfd + 1, + (fd_set *) temp, + 0, + 0, + timeout); + if (result == -1) + ACE_ERROR ((LM_ERROR, + "(%P|%t) %p\n", + "select")); + else if (result == 0 && verbose) + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) select timed out\n")); + else + { + if (temp.is_set (twoway_acceptor.get_handle ())) + { + int r = twoway_acceptor.accept (new_stream); + while (r == -1 && errno == EAGAIN) + r = twoway_acceptor.accept (new_stream); + if (r == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "accept")); + continue; + } + else + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) spawning twoway server\n")); + + // Run the twoway server. + twoway_server (new_stream); + } + if (temp.is_set (oneway_acceptor.get_handle ())) + { + if (oneway_acceptor.accept (new_stream) == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "accept")); + continue; + } + else + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) spawning oneway server\n")); + + // Run the oneway server. + oneway_server (new_stream); + } + } + } + + /* NOTREACHED */ +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + u_short port = ACE_DEFAULT_SERVER_PORT; + + if (argc > 1) + port = ACE_OS::atoi (argv[1]); + + return run_event_loop (port); +} diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-server.cpp b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server.cpp new file mode 100644 index 00000000000..c1f173cd72f --- /dev/null +++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server.cpp @@ -0,0 +1,430 @@ +// $Id$ + +// This example tests the features of the <ACE_SSL_SOCK_Acceptor>, +// <ACE_SSL_SOCK_Stream>, and <ACE_Svc_Handler> classes. If the platform +// supports threads it uses a thread-per-connection concurrency model. +// Otherwise, it uses a single-threaded iterative server model. + +#include "ace/Thread_Manager.h" +#include "ace/Handle_Set.h" +#include "ace/Profile_Timer.h" +#include "ace/OS_NS_sys_select.h" + +#include "ace/SSL/SSL_SOCK_Acceptor.h" + +ACE_RCSID(SSL_SAP, SSL_server, "$Id$") + +// Are we running verbosely? +static int verbose = 0; + +static void +run_server (ACE_THR_FUNC server, + ACE_SSL_SOCK_Stream * new_stream) +{ +#if defined (ACE_HAS_THREADS) + // Spawn a new thread and run the new connection in that thread of + // control using the <server> function as the entry point. + if (ACE_Thread_Manager::instance ()->spawn (server, + (void *) new_stream, + THR_DETACHED) == -1) + ACE_ERROR ((LM_ERROR, + "(%P|%t) %p\n", + "spawn")); +#else + (*server) ((void *) new_stream); +#endif /* ACE_HAS_THREADS */ +} + +// Function entry point into the twoway server task. + +static ACE_THR_FUNC_RETURN +twoway_server (void *arg) +{ + ACE_INET_Addr cli_addr; + ACE_SSL_SOCK_Stream * new_stream = (ACE_SSL_SOCK_Stream *) arg; + + // Make sure we're not in non-blocking mode. + if (new_stream->disable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "disable"), + 0); + else if (new_stream->get_remote_addr (cli_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "get_remote_addr"), + 0); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) client %s connected from %d\n", + cli_addr.get_host_name (), + cli_addr.get_port_number ())); + + size_t total_bytes = 0; + size_t message_count = 0; + + char *request = 0; + + // Read data from client (terminate on error). + + for (;;) + { + ACE_INT32 len; + + ssize_t r_bytes = new_stream->recv_n ((void *) &len, + sizeof (ACE_INT32)); + if (r_bytes == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "recv")); + break; + } + else if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reached end of input, connection closed by client\n")); + break; + } + else if (r_bytes != sizeof (ACE_INT32)) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) %p\n", + "recv_n failed")); + break; + } + else + { + len = ntohl (len); + ACE_NEW_RETURN (request, + char [len], + 0); + } + + // Subtract off the sizeof the length prefix. + r_bytes = new_stream->recv_n (request, + len - sizeof (ACE_UINT32)); + if (r_bytes == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "recv")); + break; + } + else if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reached end of input, " + "connection closed by client\n")); + break; + } + else if (verbose + && ACE::write_n (ACE_STDOUT, + request, + r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, + "%p\n", + "ACE::write_n")); + else if (new_stream->send_n (request, + r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, + "%p\n", + "send_n")); + + total_bytes += size_t (r_bytes); + message_count++; + + delete [] request; + request = 0; + } + + // Close new endpoint (listening endpoint stays open). + new_stream->close (); + + delete new_stream; + + delete [] request; + + return 0; +} + +// Function entry point into the oneway server task. + +static ACE_THR_FUNC_RETURN +oneway_server (void *arg) +{ + ACE_INET_Addr cli_addr; + ACE_SSL_SOCK_Stream * new_stream = (ACE_SSL_SOCK_Stream *) arg; + + // Make sure we're not in non-blocking mode. + if (new_stream->disable (ACE_NONBLOCK) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "disable"), + 0); + else if (new_stream->get_remote_addr (cli_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "get_remote_addr"), + 0); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) client %s connected from %d\n", + cli_addr.get_host_name (), + cli_addr.get_port_number ())); + + // Timer business + ACE_Profile_Timer timer; + timer.start (); + + size_t total_bytes = 0; + size_t message_count = 0; + + char *request = 0; + + // Read data from client (terminate on error). + + for (;;) + { + ACE_INT32 len; + + ssize_t r_bytes = new_stream->recv_n ((void *) &len, + sizeof (ACE_INT32)); + if (r_bytes == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "recv")); + break; + } + else if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reached end of input, connection closed by client\n")); + break; + } + else if (r_bytes != sizeof (ACE_INT32)) + { + ACE_ERROR ((LM_ERROR, + "(%P|%t) %p\n", + "recv_n failed")); + break; + } + else + { + len = ntohl (len); + ACE_NEW_RETURN (request, + char [len], + 0); + } + + // Subtract off the sizeof the length prefix. + r_bytes = new_stream->recv_n (request, + len - sizeof (ACE_UINT32)); + + if (r_bytes == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "recv")); + break; + } + else if (r_bytes == 0) + { + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) reached end of input, connection closed by client\n")); + break; + } + else if (verbose + && ACE::write_n (ACE_STDOUT, request, r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, + "%p\n", + "ACE::write_n")); + + total_bytes += size_t (r_bytes); + message_count++; + + delete [] request; + request = 0; + } + + timer.stop (); + + ACE_Profile_Timer::ACE_Elapsed_Time et; + timer.elapsed_time (et); + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\t\treal time = %f secs \n") + ACE_TEXT ("\t\tuser time = %f secs \n") + ACE_TEXT ("\t\tsystem time = %f secs\n"), + et.real_time, + et.user_time, + et.system_time)); + + double messages_per_sec = double (message_count) / et.real_time; + + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("\t\tmessages = %d\n") + ACE_TEXT ("\t\ttotal bytes = %d\n") + ACE_TEXT ("\t\tmbits/sec = %f\n") + ACE_TEXT ("\t\tusec-per-message = %f\n") + ACE_TEXT ("\t\tmessages-per-second = %0.00f\n"), + message_count, + total_bytes, + (((double) total_bytes * 8) / et.real_time) / (double) (1024 * 1024), + (et.real_time / (double) message_count) * 1000000, + messages_per_sec < 0 ? 0 : messages_per_sec)); + + // Close new endpoint (listening endpoint stays open). + new_stream->close (); + + delete new_stream; + + delete [] request; + + return 0; +} + +static int +run_event_loop (u_short port) +{ + // Raise the socket handle limit to the maximum. + ACE::set_handle_limit (); + + // Create the oneway and twoway acceptors. + ACE_SSL_SOCK_Acceptor twoway_acceptor; + ACE_SSL_SOCK_Acceptor oneway_acceptor; + + // Create the oneway and twoway server addresses. + ACE_INET_Addr twoway_server_addr (port); + ACE_INET_Addr oneway_server_addr (port + 1); + + // Create acceptors, reuse the address. + if (twoway_acceptor.open (twoway_server_addr, 1) == -1 + || oneway_acceptor.open (oneway_server_addr, 1) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "open"), + 1); + else if (twoway_acceptor.get_local_addr (twoway_server_addr) == -1 + || oneway_acceptor.get_local_addr (oneway_server_addr) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "get_local_addr"), + 1); + + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) starting twoway server at port %d and oneway server at port %d\n", + twoway_server_addr.get_port_number (), + oneway_server_addr.get_port_number ())); + + // Keep these objects out here to prevent excessive constructor + // calls within the loop. + + ACE_Handle_Set handle_set; + handle_set.set_bit (twoway_acceptor.get_handle ()); + handle_set.set_bit (oneway_acceptor.get_handle ()); + + ACE_SSL_SOCK_Stream * new_stream = 0; + + // Performs the iterative server activities. + for (;;) + { + ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT); + ACE_Handle_Set temp = handle_set; + + int result = ACE_OS::select (int (oneway_acceptor.get_handle ()) + 1, + (fd_set *) temp, + 0, + 0, + timeout); + if (result == -1) + ACE_ERROR ((LM_ERROR, + "(%P|%t) %p\n", + "select")); + else if (result == 0 && verbose) + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) select timed out\n")); + else + { + // A new ACE_SSL_SOCK_Stream must be initialized for each + // connection. However, it retains (SSL) state so simply + // initializing a new ACE_SSL_SOCK_Stream by passing it a + // handle isn't enough, nor is it allowed. Such a scheme is + // is sometimes done with the non-SSL aware + // ACE_SOCK_Stream. An ACE_SSL_SOCK_Stream should only be + // initialized by an ACE_SSL_SOCK_Acceptor (server side), or an + // ACE_SSL_SOCK_Connector (client side). + // + // It is also possible to copy or assign an + // ACE_SSL_SOCK_Stream since it implements both + // methods/operators. However, the user must ensure that + // the copy or assignment is atomic. + + if (temp.is_set (twoway_acceptor.get_handle ())) + { + ACE_NEW_RETURN (new_stream, + ACE_SSL_SOCK_Stream, + -1); + + if (twoway_acceptor.accept (*new_stream) == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "accept")); + + delete new_stream; + + continue; + } + else + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) spawning twoway server\n")); + + // Run the twoway server. + run_server (twoway_server, + new_stream); + } + if (temp.is_set (oneway_acceptor.get_handle ())) + { + ACE_NEW_RETURN (new_stream, + ACE_SSL_SOCK_Stream, + -1); + + if (oneway_acceptor.accept (*new_stream) == -1) + { + ACE_ERROR ((LM_ERROR, "%p\n", "accept")); + + delete new_stream; + + continue; + } + else + ACE_DEBUG ((LM_DEBUG, + "(%P|%t) spawning oneway server\n")); + + // Run the oneway server. + run_server (oneway_server, + new_stream); + } + } + } + + /* NOTREACHED */ +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_SSL_Context *context = ACE_SSL_Context::instance (); + + context->certificate ("./dummy.pem", SSL_FILETYPE_PEM); + context->private_key ("./key.pem", SSL_FILETYPE_PEM); + + u_short port = ACE_DEFAULT_SERVER_PORT; + + if (argc > 1) + port = ACE_OS::atoi (argv[1]); + + return run_event_loop (port); +} diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL_SAP.mpc b/ACE/examples/IPC_SAP/SSL_SAP/SSL_SAP.mpc new file mode 100644 index 00000000000..f67fdb7c2a0 --- /dev/null +++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL_SAP.mpc @@ -0,0 +1,50 @@ +// -*- MPC -*- +// $Id$ + +project(*client) : aceexe, ssl { + avoids += ace_for_tao + exename = client + Source_Files { + SSL-client.cpp + } +} + +project(*client_simple) : aceexe, ssl { + avoids += ace_for_tao + exename = client-simple + Source_Files { + SSL-client-simple.cpp + } +} + +project(*server) : aceexe, ssl { + avoids += ace_for_tao + exename = server + Source_Files { + SSL-server.cpp + } +} + +project(*server_fancy) : aceexe, ssl { + avoids += ace_for_tao + exename = server-fancy + Source_Files { + SSL-server-fancy.cpp + } +} + +project(*server_poll) : aceexe, ssl { + avoids += ace_for_tao + exename = server-poll + Source_Files { + SSL-server-poll.cpp + } +} + +project(*server_simple) : aceexe, ssl { + avoids += ace_for_tao + exename = server-simple + Source_Files { + SSL-server-simple.cpp + } +} diff --git a/ACE/examples/IPC_SAP/SSL_SAP/dummy.pem b/ACE/examples/IPC_SAP/SSL_SAP/dummy.pem new file mode 100644 index 00000000000..d631a33b956 --- /dev/null +++ b/ACE/examples/IPC_SAP/SSL_SAP/dummy.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICaTCCAdICAQAwDQYJKoZIhvcNAQEEBQAwcjELMAkGA1UEBhMCVVMxCzAJBgNV +BAgTAkNBMQ8wDQYDVQQHEwZJcnZpbmUxDDAKBgNVBAoTA09DSTEMMAoGA1UECxMD +VEFPMREwDwYDVQQDEwhwcml5YW5rYTEWMBQGCSqGSIb3DQEJARYHcGdvbnRsYTAe +Fw0wMTAzMjkwNDM4NDZaFw0wMTA0MjgwNDM4NDZaMIGHMQswCQYDVQQGEwJVUzEL +MAkGA1UECBMCQ0ExDzANBgNVBAcTBklydmluZTEdMBsGA1UEChMUT2JqZWN0IENv +bXB1dGluZyBJbmMxEDAOBgNVBAsTB09DSStUQU8xETAPBgNVBAMTCHByaXlhbmth +MRYwFAYJKoZIhvcNAQkBFgdwZ29udGxhMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB +iQKBgQClC6z/bX1JHF1Hg06NCnBmsikEjViEdJFuqLOH3rXSGbm+2Eo+IO4dHlFS +u6+Ntk4olBZTuf0DqzyEgrOiN7cnKXpxJzb1cwCmVkvDQISMygf4o66+CHtF8o8Z +Sbi9F5u9W+MILaoCexEIVZqfHffcGxvm5O2MorBSQNka3NcC3wIDAQABMA0GCSqG +SIb3DQEBBAUAA4GBADuKX6kllE2sNdQYMbSzt5C/lcpgcsK0BR6L01cQA95b5TvL +HsKMeeeRj2npR4EPXY2gqgWTrKHZvf01aoKE5LuyzSQ+qfFMuEfo7+p9SYIuIrLD +5+J0wOwN0R0YZAEY5gCAqRGw26dwWDai+PASPsx0YXV1y9jBB1FFtUFgrpR8 +-----END CERTIFICATE----- diff --git a/ACE/examples/IPC_SAP/SSL_SAP/key.pem b/ACE/examples/IPC_SAP/SSL_SAP/key.pem new file mode 100644 index 00000000000..54ff8f0f488 --- /dev/null +++ b/ACE/examples/IPC_SAP/SSL_SAP/key.pem @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQClC6z/bX1JHF1Hg06NCnBmsikEjViEdJFuqLOH3rXSGbm+2Eo+ +IO4dHlFSu6+Ntk4olBZTuf0DqzyEgrOiN7cnKXpxJzb1cwCmVkvDQISMygf4o66+ +CHtF8o8ZSbi9F5u9W+MILaoCexEIVZqfHffcGxvm5O2MorBSQNka3NcC3wIDAQAB +AoGALYq/PexUeewdwTH2ZuzOf0gCEYN/PW19A/ABOii2OzdmDcdZFTO5AMfw4Mdx +dcUsY/4Y+xmDO5Pwqw/1yXleTDqvEKCgIEHN4NWnYYSiZOy3LBzQ8XaMZ7/2PCqc +s4EtesuRB2kZ7PH2R1vJfyGIxZPaO5MOFbs3QFnpBUjqOmECQQDQCYgnBcshCEro +gsrTjxtZiVHjmXEo0Uo2m4CBQW1PLJmmUXBzivGkVFfhjKULjwvso3BePfmzy9wP +7YFjVXN9AkEAyxjBXi2kYCcXfGQiNuIrLkyVXeGR2YWnhzS2nL1TjNngmCBbnj48 +qvoqOUQgFK0AeTe/x7lb4Cf24ejWF5vmiwJALensorAkpKWv4qD7IrXy00/7QsAa +uWd3eZXYRq6p8U9mmc5fgyCnNB1pR95CjsqDVza7FhGXipbzepBwffveAQJBAMKc +mxYyqDMW4nNoxDxRJs17xxkpwAdvAiQWB/JTnQ737DX5s7EDtECl7PXo6NDHIhAF +srigToCR6wl4gkYnNpcCQHmlfa9Duf3VJI/XeHE9ZU8vS4qgx0Ikfh01xCqWlsaq +nPRmtfktt4P8gxlryZCEPpRs9l/XwQY6tnpHr5EmV2Y= +-----END RSA PRIVATE KEY----- diff --git a/ACE/examples/IPC_SAP/SSL_SAP/local_data b/ACE/examples/IPC_SAP/SSL_SAP/local_data new file mode 100644 index 00000000000..c0119859a28 --- /dev/null +++ b/ACE/examples/IPC_SAP/SSL_SAP/local_data @@ -0,0 +1 @@ +I am Iron man! diff --git a/ACE/examples/IPC_SAP/SSL_SAP/summarize b/ACE/examples/IPC_SAP/SSL_SAP/summarize new file mode 100755 index 00000000000..ee8ffd2df25 --- /dev/null +++ b/ACE/examples/IPC_SAP/SSL_SAP/summarize @@ -0,0 +1,45 @@ +eval '(exit $?0)' && eval 'exec perl -w -S $0 ${1+"$@"}' + & eval 'exec perl -w -S $0 $argv:q' + if 0; + +# $Id$ +# +# Summarizes results from a series of runs of run_test, with +# different numbers of clients. Example usage: +# +# $ for i in 1 2 5 10 15 20 25 30 35 40 45 50; do ./run_test $i; done +# $ ./summarize +# +# The first three lines above let this script run without specifying the +# full path to perl, as long as it is in the user's PATH. +# Taken from perlrun man page. + +@files = glob 'client-*.log'; +@total_threads = (); + +foreach $file (@files) { + my ($i); + ($i = $file) =~ s/client-(\d+).log/$1/; + push @total_threads, $i; +} + +print "No.of threads\t\tAverage Latency\n\n"; + +foreach $total_threads (sort {$a <=> $b} @total_threads) { + undef $high_latency; + + $high_latency = 0; + open (FILE, "client-${total_threads}.log") || + die "$0: unable to open \"client-${total_threads}.log\"\n"; + while ($line = <FILE>) { + if ($line =~ /.*usec-per-message = ([\d\.]+)/) + { + $high_latency += $1 ; + $number++; + } + } + close FILE; + + printf "%3d\t\t\t%8f\n", + $total_threads, $high_latency/$number; +} diff --git a/ACE/examples/IPC_SAP/TLI_SAP/CPP-ATM-client.cpp b/ACE/examples/IPC_SAP/TLI_SAP/CPP-ATM-client.cpp new file mode 100644 index 00000000000..35dda19f05e --- /dev/null +++ b/ACE/examples/IPC_SAP/TLI_SAP/CPP-ATM-client.cpp @@ -0,0 +1,162 @@ +// $Id$ + +#include "ace/TLI_Connector.h" +#include "ace/ATM_QoS.h" +#include "ace/ATM_Addr.h" +#include "ace/Log_Msg.h" + +ACE_RCSID(TLI_SAP, CPP_ATM_client, "$Id$") + +#if defined (ACE_HAS_FORE_ATM_XTI) + +/* ACE_XTI/ATM Client */ + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc < 2) + ACE_ERROR_RETURN ((LM_ERROR, + "Usage: %s [-s selector] hostname [QoS in KB/sec]\n", + argv[0]), + 1); + + unsigned char selector = ACE_ATM_Addr::DEFAULT_SELECTOR; + int selector_specified = 0; + extern int optind; + int opt; + while ((opt = ACE_OS::getopt (argc, argv, "s:?h")) != EOF) + { + switch(opt) + { + case 's': + selector = ACE_OS::atoi (optarg); + selector_specified = 1; + break; + case '?': + case 'h': + ACE_ERROR_RETURN ((LM_ERROR, + "Usage: %s hostname [-s selector] [QoS in KB/s]\n", + argv[0]), + 1); + } // switch + } // while getopt + + const char *host = argv[optind]; + + int rate = (argc == 3) ? ACE_OS::atoi (argv[2]) : + (argc == 5) ? ACE_OS::atoi (argv[4]) : 0; + // The timeout really gets ignored since FORE's drivers don't work when + // ioctl or fcntl calls are made on the transport id/file descriptor + int timeout = ACE_DEFAULT_TIMEOUT; + + char buf[BUFSIZ]; + + ACE_TLI_Stream cli_stream; + + ACE_ATM_Addr remote_addr (host); + if (selector_specified) + remote_addr.set_selector(selector); + char hostname[MAXNAMELEN]; + ACE_OS::hostname(hostname, MAXNAMELEN); + ACE_ATM_Addr local_addr (hostname); + + // In order to construct connections options the file handle is + // needed. Therefore, we need to open the TLI_Stream before we + // construct the options. + if (cli_stream.open (ACE_XTI_ATM_DEVICE, O_RDWR, 0) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "open failed"), + 1); + + ACE_DEBUG ((LM_DEBUG, + "starting non-blocking connect\n")); + + // Initiate timed, non-blocking connection with server. + ACE_TLI_Connector con; + + // Construct QoS options - currently FORE only supports bandwidth + ACE_ATM_QoS qos; + qos.set_rate(cli_stream.get_handle (), + rate, + ACE_ATM_QoS::OPT_FLAGS_CPID); + + struct netbuf optbuf = qos.get_qos(); +// long optlen = 0; +// char *options = remote_addr.construct_options (cli_stream.get_handle (), +// rate, +// ACE_ATM_Addr::OPT_FLAGS_CPID, +// &optlen); +// struct netbuf optbuf; +// optbuf.len = optlen; +// optbuf.buf = options; + + // Not sure why but reuse_addr set to true/1 causes problems for + // FORE/XTI/ATM - this is now handled in ACE_TLI_Connector::connect() + if (con.connect (cli_stream, + remote_addr, + (ACE_Time_Value *) &ACE_Time_Value::zero, + local_addr, + 1, + O_RDWR, + 0, + ACE_XTI_ATM_DEVICE, + 0, + 1, + 0, + &optbuf) == -1) + { + if (errno != EWOULDBLOCK) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "connection failed"), + 1); + + ACE_DEBUG ((LM_DEBUG, + "starting timed connect\n")); + + // Check if non-blocking connection is in progress, and wait up + // to timeout seconds for it to complete. + ACE_Time_Value tv (timeout); + + if (con.complete (cli_stream, + &remote_addr, + &tv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "connection failed"), + 1); + else + ACE_DEBUG ((LM_DEBUG, + "connected to %s\n", + remote_addr.addr_to_string ())); + } + + // Send data to server (correctly handles "incomplete writes"). + + for (int r_bytes; + (r_bytes = ACE_OS::read (ACE_STDIN, buf, sizeof buf)) > 0; + ) + if (cli_stream.send_n (buf, + r_bytes, + 0) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "send_n"), + 1); + + // Explicitly close the connection. + if (cli_stream.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "close"), + -1); + return 0; +} +#else +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "your platform isn't configured to support XTI/ATM\n"), + 1); +} +#endif /* ACE_HAS_TLI */ diff --git a/ACE/examples/IPC_SAP/TLI_SAP/CPP-ATM-server.cpp b/ACE/examples/IPC_SAP/TLI_SAP/CPP-ATM-server.cpp new file mode 100644 index 00000000000..5f45d465b49 --- /dev/null +++ b/ACE/examples/IPC_SAP/TLI_SAP/CPP-ATM-server.cpp @@ -0,0 +1,114 @@ +// $Id$ + +#include "ace/TLI_Acceptor.h" +#include "ace/ATM_Addr.h" +#include "ace/Log_Msg.h" + +ACE_RCSID(TLI_SAP, CPP_ATM_server, "$Id$") + +#if defined (ACE_HAS_FORE_ATM_XTI) +// ACE_TLI Server + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT); + + unsigned char selector = ACE_ATM_Addr::DEFAULT_SELECTOR; + int selector_specified = 0; + int opt; + while ((opt = ACE_OS::getopt (argc, argv, "s:?h")) != EOF) + { + switch(opt) + { + case 's': + selector = ACE_OS::atoi (optarg); + selector_specified = 1; + break; + case '?': + case 'h': + ACE_ERROR_RETURN ((LM_ERROR, + "Usage: %s [-s selector]\n", argv[0]), + 1); + } // switch + } // while getopt + + // Create a server address. + ACE_ATM_Addr addr; + if (selector_specified) + addr.set_selector(selector); + + // Create a server, reuse the addr. + ACE_TLI_Acceptor peer_acceptor; + + // Not sure why but reuse_addr set to true/1 causes problems for + // FORE/XTI/ATM - this is now handled in ACE_TLI_Acceptor::open() + if (peer_acceptor.open (addr, + 1, + O_RDWR, + 0, + 5, + ACE_XTI_ATM_DEVICE) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "open"), + -1); + + ACE_TLI_Stream new_stream; + + ACE_DEBUG ((LM_DEBUG, + "starting server at address %s\n", + addr.addr_to_string ())); + + + // Performs the iterative server activities + + for (;;) + { + char buf[BUFSIZ]; + + // Create a new ACE_TLI_Stream endpoint (note automatic restart + // if errno == EINTR). + if (peer_acceptor.accept (new_stream, + &addr, + &timeout) == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "accept")); + continue; + } + + ACE_DEBUG ((LM_DEBUG, + "client %s connected\n", + addr.addr_to_string ())); + + // Read data from client (terminate on error). + + for (int r_bytes; + (r_bytes = new_stream.recv (buf, sizeof buf, 0)) > 0; ) + if (ACE_OS::write (ACE_STDOUT, + buf, + r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, + "%p\n", + "ACE::send_n")); + + // Close new endpoint (listening endpoint stays open). + if (new_stream.close () == -1) + ACE_ERROR ((LM_ERROR, + "%p\n", + "close")); + + } + /* NOTREACHED */ + return 0; +} +#else +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "your platform isn't configured to support XTI/ATM\n"), + 1); +} +#endif /* ACE_HAS_TLI */ diff --git a/ACE/examples/IPC_SAP/TLI_SAP/CPP-client.cpp b/ACE/examples/IPC_SAP/TLI_SAP/CPP-client.cpp new file mode 100644 index 00000000000..550356bba2e --- /dev/null +++ b/ACE/examples/IPC_SAP/TLI_SAP/CPP-client.cpp @@ -0,0 +1,94 @@ +// $Id$ + +#include "ace/TLI_Connector.h" +#include "ace/INET_Addr.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_unistd.h" +#include "ace/Time_Value.h" + +ACE_RCSID(TLI_SAP, CPP_client, "$Id$") + +#if defined (ACE_HAS_TLI) + +/* ACE_TLI Client */ + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + const ACE_TCHAR *host = argc > 1 ? argv[1] : ACE_DEFAULT_SERVER_HOST; + u_short r_port = argc > 2 ? ACE_OS::atoi (argv[2]) : ACE_DEFAULT_SERVER_PORT; + int timeout = argc > 3 ? ACE_OS::atoi (argv[3]) : ACE_DEFAULT_TIMEOUT; + u_short l_port = argc > 4 ? ACE_OS::atoi (argv[4]) : ACE_DEFAULT_LOCAL_PORT; + + char buf[BUFSIZ]; + + ACE_TLI_Stream cli_stream; + + ACE_INET_Addr remote_addr (r_port, host); + ACE_INET_Addr local_addr (l_port); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("starting non-blocking connect\n"))); + + // Initiate timed, non-blocking connection with server. + ACE_TLI_Connector con; + + if (con.connect (cli_stream, + remote_addr, + (ACE_Time_Value *) &ACE_Time_Value::zero, + local_addr, + 1) == -1) + { + if (errno != EWOULDBLOCK) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("connection failed")), + 1); + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("starting timed connect\n"))); + + // Check if non-blocking connection is in progress, and wait up + // to timeout seconds for it to complete. + ACE_Time_Value tv (timeout); + + if (con.complete (cli_stream, + &remote_addr, + &tv) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("connection failed")), + 1); + else + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("connected to %s\n"), + remote_addr.get_host_name ())); + } + + // Send data to server (correctly handles "incomplete writes"). + + for (int r_bytes; + (r_bytes = ACE_OS::read (ACE_STDIN, buf, sizeof buf)) > 0; + ) + if (cli_stream.send_n (buf, + r_bytes, + 0) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("send_n")), + 1); + + // Explicitly close the connection. + if (cli_stream.close () == -1) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("%p\n"), + ACE_TEXT ("close")), + -1); + return 0; +} +#else +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("your platform isn't configured to support TLI\n")), + 1); +} +#endif /* ACE_HAS_TLI */ diff --git a/ACE/examples/IPC_SAP/TLI_SAP/CPP-server.cpp b/ACE/examples/IPC_SAP/TLI_SAP/CPP-server.cpp new file mode 100644 index 00000000000..a85070ccb9e --- /dev/null +++ b/ACE/examples/IPC_SAP/TLI_SAP/CPP-server.cpp @@ -0,0 +1,89 @@ +// $Id$ + +#include "ace/TLI_Acceptor.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID(TLI_SAP, CPP_server, "$Id$") + +#if defined (ACE_HAS_TLI) +// ACE_TLI Server + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + u_short port = argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_DEFAULT_SERVER_PORT; + ACE_Time_Value timeout (argc > 2 ? ACE_OS::atoi (argv[2]) : ACE_DEFAULT_TIMEOUT); + + // Create a server address. + ACE_INET_Addr addr (port); + + // Create a server, reuse the addr. + ACE_TLI_Acceptor peer_acceptor; + + // Not sure why but reuse_addr set to true/1 causes problems for + // FORE/XTI/ATM - this is now handled in ACE_TLI_Acceptor::open() + if (peer_acceptor.open (addr, 1) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "open"), + -1); + + ACE_TLI_Stream new_stream; + + ACE_DEBUG ((LM_DEBUG, + "starting server at host %s\n", + addr.get_host_name ())); + + // Performs the iterative server activities + + for (;;) + { + char buf[BUFSIZ]; + + // Create a new ACE_TLI_Stream endpoint (note automatic restart + // if errno == EINTR). + if (peer_acceptor.accept (new_stream, + &addr, + &timeout) == -1) + { + ACE_ERROR ((LM_ERROR, + "%p\n", + "accept")); + continue; + } + + ACE_DEBUG ((LM_DEBUG, + "client %s connected\n", + addr.get_host_name ())); + + // Read data from client (terminate on error). + + for (int r_bytes; + (r_bytes = new_stream.recv (buf, sizeof buf)) > 0; ) + if (ACE_OS::write (ACE_STDOUT, + buf, + r_bytes) != r_bytes) + ACE_ERROR ((LM_ERROR, + "%p\n", + "ACE::send_n")); + + // Close new endpoint (listening endpoint stays open). + if (new_stream.close () == -1) + ACE_ERROR ((LM_ERROR, + "%p\n", + "close")); + + } + /* NOTREACHED */ + return 0; +} +#else +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "your platform isn't configured to support TLI\n"), + 1); +} +#endif /* ACE_HAS_TLI */ diff --git a/ACE/examples/IPC_SAP/TLI_SAP/Makefile.am b/ACE/examples/IPC_SAP/TLI_SAP/Makefile.am new file mode 100644 index 00000000000..3f9a09726d2 --- /dev/null +++ b/ACE/examples/IPC_SAP/TLI_SAP/Makefile.am @@ -0,0 +1,132 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +## Makefile.TLI_SAP_ATM_Client.am + +noinst_PROGRAMS = ATM-client + +ATM_client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +ATM_client_SOURCES = \ + CPP-ATM-client.cpp + +ATM_client_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.TLI_SAP_ATM_Server.am + +noinst_PROGRAMS += ATM-server + +ATM_server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +ATM_server_SOURCES = \ + CPP-ATM-server.cpp + +ATM_server_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.TLI_SAP_CPP_Client.am + +noinst_PROGRAMS += CPP-client + +CPP_client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +CPP_client_SOURCES = \ + CPP-client.cpp + +CPP_client_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.TLI_SAP_CPP_Server.am + +noinst_PROGRAMS += CPP-server + +CPP_server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +CPP_server_SOURCES = \ + CPP-server.cpp + +CPP_server_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.TLI_SAP_Db_Client.am + +noinst_PROGRAMS += db-client + +db_client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +db_client_SOURCES = \ + db-client.cpp + +db_client_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.TLI_SAP_Db_Server.am + +noinst_PROGRAMS += db-server + +db_server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +db_server_SOURCES = \ + db-server.cpp + +db_server_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.TLI_SAP_Ftp_Client.am + +noinst_PROGRAMS += ftp-client + +ftp_client_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +ftp_client_SOURCES = \ + ftp-client.cpp + +ftp_client_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Makefile.TLI_SAP_Ftp_Server.am + +noinst_PROGRAMS += ftp-server + +ftp_server_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +ftp_server_SOURCES = \ + ftp-server.cpp + +ftp_server_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/IPC_SAP/TLI_SAP/TLI_SAP.mpc b/ACE/examples/IPC_SAP/TLI_SAP/TLI_SAP.mpc new file mode 100644 index 00000000000..0fe9b1aa17b --- /dev/null +++ b/ACE/examples/IPC_SAP/TLI_SAP/TLI_SAP.mpc @@ -0,0 +1,58 @@ +// -*- MPC -*- +// $Id$ + +project(*ATM_client) : aceexe { + exename = ATM-client + Source_Files { + CPP-ATM-client.cpp + } +} + +project(*ATM_server) : aceexe { + exename = ATM-server + Source_Files { + CPP-ATM-server.cpp + } +} + +project(*CPP_client) : aceexe { + exename = CPP-client + Source_Files { + CPP-client.cpp + } +} + +project(*CPP_server) : aceexe { + exename = CPP-server + Source_Files { + CPP-server.cpp + } +} + +project(*db_client) : aceexe { + exename = db-client + Source_Files { + db-client.cpp + } +} + +project(*db_server) : aceexe { + exename = db-server + Source_Files { + db-server.cpp + } +} + +project(*ftp_client) : aceexe { + exename = ftp-client + Source_Files { + ftp-client.cpp + } +} + +project(*ftp_server) : aceexe { + exename = ftp-server + Source_Files { + ftp-server.cpp + } +} diff --git a/ACE/examples/IPC_SAP/TLI_SAP/db-client.cpp b/ACE/examples/IPC_SAP/TLI_SAP/db-client.cpp new file mode 100644 index 00000000000..6136d0ae4c5 --- /dev/null +++ b/ACE/examples/IPC_SAP/TLI_SAP/db-client.cpp @@ -0,0 +1,60 @@ +// $Id$ + +#include "ace/TLI_Connector.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_string.h" + +ACE_RCSID(TLI_SAP, db_client, "$Id$") + +#if defined (ACE_HAS_TLI) +const int MAXLINE = 255; + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc < 2) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Usage: %s employee_id [server-host port-number]\n"), + argv[0]), + -1); + + const ACE_TCHAR *emp_num = argv[1]; + const ACE_TCHAR *host_name = argc < 3 ? ACE_DEFAULT_SERVER_HOST : argv[2]; + unsigned short port = argc < 4 ? ACE_DEFAULT_SERVER_PORT : ACE_OS::atoi (argv[3]); + int n; + char buf[MAXLINE]; + + ACE_TLI_Stream client; + ACE_TLI_Connector con; + + if (con.connect (client, ACE_INET_Addr (port, host_name)) == -1) + ACE_OS::t_error ((char *) host_name), ACE_OS::exit (1); + + ACE_OS::strcpy (buf, ACE_TEXT_ALWAYS_CHAR (emp_num)); + n = ACE_OS::strlen (buf); + + if (client.send_n (buf, n) != n) + ACE_OS::t_error ("client.send error"); + + if (client.recv (buf, MAXLINE) == -1 && t_errno != TLOOK && client.look () != T_DISCONNECT) + ACE_OS::t_error ("client.recv error"); + + if (ACE_OS::strcmp (buf, "ERROR") == 0) + ACE_OS::printf ("Employee ID %s not in database\n", emp_num); + else + ACE_OS::printf ("Employee name requested is: %s\n", buf); + + if (client.close () == -1) + ACE_OS::t_error ("cli_close"), ACE_OS::exit (1); + + return 0; +} +#else +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "your platform isn't configured to support TLI\n"), + 1); +} +#endif /* ACE_HAS_TLI */ diff --git a/ACE/examples/IPC_SAP/TLI_SAP/db-server.cpp b/ACE/examples/IPC_SAP/TLI_SAP/db-server.cpp new file mode 100644 index 00000000000..3b547e154a3 --- /dev/null +++ b/ACE/examples/IPC_SAP/TLI_SAP/db-server.cpp @@ -0,0 +1,121 @@ +// $Id$ + +// Simple multi-threaded database server example. + +#include "ace/OS_NS_stdio.h" +#include "ace/TLI_Acceptor.h" +#include "ace/Thread_Manager.h" + +ACE_RCSID(TLI_SAP, db_server, "$Id$") + +#if defined (ACE_HAS_THREADS) && defined (ACE_HAS_TLI) + +// Global thread manager. +ACE_Thread_Manager thr_mgr; + +void * +lookup_name (ACE_HANDLE handle) +{ + enum + { + MAXLINE = 255, + EMPNAMELEN = 512 + }; + + static struct + { + int emp_id; + const char *emp_name; + } employee_db[] = + { + {123, "John Wayne Bobbit"}, + {124, "Woody Allen"}, + {125, "O. J. Simpson"}, + {126, "Bill Clinton"}, + {127, "Rush Limbaugh"}, + {128, "Michael Jackson"}, + {129, "Kenneth Starr"}, + {130, "Paula Jones"}, + {131, "Monica Lewinsky"}, + {132, "Marv Albert"}, + {0, ""} + }; + + int flags; + int employee_id; + int index; + int found; + ACE_TLI_Stream stream; + char recvline[MAXLINE]; + char sendline[MAXLINE]; + + ACE_DEBUG ((LM_DEBUG, + "stream handle = %d, thread id = %t\n", + handle)); + stream.set_handle (handle); + + ssize_t n = stream.recv (recvline, MAXLINE, &flags); + + if (n == -1) + ACE_OS::t_error ("stream.recv error"); + + employee_id = ACE_OS::atoi (recvline); + found = 0; + + for (index = 0; found == 0 && employee_db[index].emp_id; index++) + if (employee_id == employee_db[index].emp_id) + { + found = 1; + n = ACE_OS::sprintf (sendline, + "%s", employee_db[index].emp_name); + } + + if (found == 0) + n = ACE_OS::sprintf (sendline, "%s", "ERROR"); + + if (stream.send (sendline, n + 1, 0) == -1) + ACE_OS::t_error ("stream.send error"); + + if (stream.sndrel () == -1) + ACE_OS::t_error ("stream.send error"); + + if (stream.close () == -1) + ACE_OS::t_error ("stream.close error"); + + return 0; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + u_short port = argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_DEFAULT_SERVER_PORT; + ACE_INET_Addr l_addr (port); + ACE_TLI_Acceptor server (l_addr, 1); // Create server, reuse addr if in use. + ACE_TLI_Stream new_stream; + + // Wait for a connection from a client. This is an example of a + // concurrent server. + + for (;;) + { + if (server.accept (new_stream) == -1) + ACE_OS::t_error ("server.accept error"); + + if (thr_mgr.spawn (ACE_THR_FUNC (lookup_name), + (void *) new_stream.get_handle (), + THR_DETACHED) == -1) + ACE_DEBUG ((LM_ERROR, + "server: can't create worker thread %d\n")); + } + + ACE_NOTREACHED (return 0); +} +#else +#include <stdio.h> +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "platform isn't configured to support TLI\n"), + 1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/IPC_SAP/TLI_SAP/ftp-client.cpp b/ACE/examples/IPC_SAP/TLI_SAP/ftp-client.cpp new file mode 100644 index 00000000000..c783e0aba55 --- /dev/null +++ b/ACE/examples/IPC_SAP/TLI_SAP/ftp-client.cpp @@ -0,0 +1,54 @@ +// $Id$ + +#include "ace/TLI_Connector.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_fcntl.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_stdlib.h" +#include "ace/OS_NS_unistd.h" + +ACE_RCSID(TLI_SAP, ftp_client, "$Id$") + +#if defined (ACE_HAS_TLI) + +int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + if (argc < 2) + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("Usage: %s filename ") + ACE_TEXT ("[server-host port-number]\n"), + argv[0]), + 1); + + const ACE_TCHAR *filename = argv[1]; + const ACE_TCHAR *host_name = argc < 3 ? ACE_DEFAULT_SERVER_HOST : argv[2]; + u_short port = argc < 4 ? ACE_DEFAULT_SERVER_PORT : ACE_OS::atoi (argv[3]); + + ACE_TLI_Stream client; + ACE_TLI_Connector con; + int fd; + char buf[BUFSIZ]; + + if (con.connect (client, ACE_INET_Addr (port, host_name)) == -1) + ACE_OS::t_error ((char *) host_name), ACE_OS::exit (1); + + if ((fd = ACE_OS::open (filename, O_RDONLY)) == -1) + ACE_OS::perror (filename), ACE_OS::exit (1); + + for (int n; (n = ACE_OS::read (fd, buf, sizeof buf)) > 0; ) + if (client.send_n (buf, n) != n) + ACE_OS::t_error ("client.send error"); + + if (client.close () == -1) + ACE_OS::t_error ("cli_close"), ACE_OS::exit (1); + + return 0; +} +#else +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("your platform isn't configured to support TLI\n")), + 1); +} +#endif /* ACE_HAS_TLI */ diff --git a/ACE/examples/IPC_SAP/TLI_SAP/ftp-server.cpp b/ACE/examples/IPC_SAP/TLI_SAP/ftp-server.cpp new file mode 100644 index 00000000000..601a90987ff --- /dev/null +++ b/ACE/examples/IPC_SAP/TLI_SAP/ftp-server.cpp @@ -0,0 +1,83 @@ +// $Id$ + +// Simple file transfer example + +#include "ace/OS_NS_stdio.h" +#include "ace/Thread_Manager.h" +#include "ace/TLI_Acceptor.h" + +ACE_RCSID(TLI_SAP, ftp_server, "$Id$") + +#if defined (ACE_HAS_THREADS) && defined (ACE_HAS_TLI) + +ACE_Thread_Manager thr_mgr; + +void * +read_file (void *fd) +{ + ACE_TLI_Stream stream; + char buf[BUFSIZ]; + int flags = 0; + ssize_t n; + + // Cast the arg to a long, first, because a pointer is the same size + // as a long on all current ACE platforms. + stream.set_handle ((int) (long) fd); + + ACE_DEBUG((LM_DEBUG, "start (tid = %t, fd = %d)\n", + stream.get_handle ())); + + while ((n = stream.recv (buf, sizeof buf, &flags)) > 0) + continue; + + ACE_UNUSED_ARG (n); + + ACE_DEBUG ((LM_DEBUG,"finish (tid = %t, fd = %d)\n", + stream.get_handle ())); + + if (stream.close () == -1) + ACE_OS::t_error ("stream.close error"); + + return 0; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + u_short port = argc > 1 ? ACE_OS::atoi (argv[1]) : ACE_DEFAULT_SERVER_PORT; + ACE_TLI_Acceptor server; + ACE_TLI_Stream new_stream; + + // Open the server and reuse the address if in use... + if (server.open (ACE_INET_Addr (port), 1) == -1) + ACE_OS::t_error ("server.open"), ACE_OS::exit (1); + + // Wait for a connection from a client. This is an example of a + // concurrent server. + + for (int count = 1; ; count++) + { + ACE_DEBUG ((LM_DEBUG, + "thread %t, blocking for accept #%d\n", + count)); + + if (server.accept (new_stream) == -1) + ACE_OS::t_error ("server.accept error"); + + else if (thr_mgr.spawn (ACE_THR_FUNC (read_file), + (void *) new_stream.get_handle (), + THR_DETACHED | THR_BOUND) == -1) + ACE_OS::perror ("can't create worker thread\n"); + } + + ACE_NOTREACHED (return 0); +} +#else +#include <stdio.h> +int ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "your platform isn't configured to support TLI\n"), + 1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/IPC_SAP/UPIPE_SAP/Makefile.am b/ACE/examples/IPC_SAP/UPIPE_SAP/Makefile.am new file mode 100644 index 00000000000..90563ab7883 --- /dev/null +++ b/ACE/examples/IPC_SAP/UPIPE_SAP/Makefile.am @@ -0,0 +1,76 @@ +## Process this file with automake to create Makefile.in +## +## $Id$ +## +## This file was generated by MPC. Any changes made directly to +## this file will be lost the next time it is generated. +## +## MPC Command: +## ./bin/mwc.pl -type automake -noreldefs ACE.mwc + +ACE_BUILDDIR = $(top_builddir) +ACE_ROOT = $(top_srcdir) + +noinst_PROGRAMS = + +## Makefile.UPIPE_SAP_Ex1.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += ex1 + +ex1_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +ex1_SOURCES = \ + ex1.cpp + +ex1_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.UPIPE_SAP_Ex2.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += ex2 + +ex2_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +ex2_SOURCES = \ + ex2.cpp + +ex2_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Makefile.UPIPE_SAP_Ex3.am + +if !BUILD_ACE_FOR_TAO + +noinst_PROGRAMS += ex3 + +ex3_CPPFLAGS = \ + -I$(ACE_ROOT) \ + -I$(ACE_BUILDDIR) + +ex3_SOURCES = \ + ex3.cpp + +ex3_LDADD = \ + $(ACE_BUILDDIR)/ace/libACE.la + +endif !BUILD_ACE_FOR_TAO + +## Clean up template repositories, etc. +clean-local: + -rm -f *~ *.bak *.rpo *.sym lib*.*_pure_* core core.* + -rm -f gcctemp.c gcctemp so_locations *.ics + -rm -rf cxx_repository ptrepository ti_files + -rm -rf templateregistry ir.out + -rm -rf ptrepository SunWS_cache Templates.DB diff --git a/ACE/examples/IPC_SAP/UPIPE_SAP/UPIPE_SAP.mpc b/ACE/examples/IPC_SAP/UPIPE_SAP/UPIPE_SAP.mpc new file mode 100644 index 00000000000..d34d8671735 --- /dev/null +++ b/ACE/examples/IPC_SAP/UPIPE_SAP/UPIPE_SAP.mpc @@ -0,0 +1,26 @@ +// -*- MPC -*- +// $Id$ + +project(*ex1) : aceexe { + avoids += ace_for_tao + exename = ex1 + Source_Files { + ex1.cpp + } +} + +project(*ex2) : aceexe { + avoids += ace_for_tao + exename = ex2 + Source_Files { + ex2.cpp + } +} + +project(*ex3) : aceexe { + avoids += ace_for_tao + exename = ex3 + Source_Files { + ex3.cpp + } +} diff --git a/ACE/examples/IPC_SAP/UPIPE_SAP/ex1.cpp b/ACE/examples/IPC_SAP/UPIPE_SAP/ex1.cpp new file mode 100644 index 00000000000..39ad86d5819 --- /dev/null +++ b/ACE/examples/IPC_SAP/UPIPE_SAP/ex1.cpp @@ -0,0 +1,183 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// examples +// +// = FILENAME +// ex1.cpp +// +// = DESCRIPTION +// Example for using <ACE_UPIPE_SAP> and <ACE_Thread> for +// intra-process communication. +// +// = AUTHOR +// Gerhard Lenzer and Douglas C. Schmidt +// +// ============================================================================ + +#include "ace/OS_main.h" +#include "ace/OS_NS_string.h" +#include "ace/Stream.h" +#include "ace/UPIPE_Acceptor.h" +#include "ace/UPIPE_Connector.h" + +ACE_RCSID(UPIPE_SAP, ex1, "$Id$") + +#if defined (ACE_HAS_THREADS) + +// Global pattern +static ACE_UPIPE_Addr addr (ACE_TEXT("pattern")); + +// peer1 thread entry point. + +static void * +peer1 (void *) +{ + ACE_UPIPE_Stream c_stream; + + ACE_DEBUG ((LM_DEBUG, + "(%t) peer1 starting connect\n")); + ACE_UPIPE_Connector con; + + if (con.connect (c_stream, addr) == -1) + ACE_ERROR ((LM_ERROR, + "(%t) peer1 ACE_UPIPE_Connector failed\n")); + + ACE_Message_Block *mb; + ACE_NEW_RETURN (mb, + ACE_Message_Block (20), + 0); + + mb->copy ("hello", 6); + + if (c_stream.send (mb) == -1) + ACE_ERROR ((LM_ERROR, + "(%t) error peer1 send\n")); + + if (c_stream.recv (mb) == -1) + ACE_ERROR ((LM_ERROR, + "(%t) error peer1 recv\n")); + + ACE_ERROR ((LM_ERROR, + "(%t) peer1 ack is \"%s\"\n", + mb->rd_ptr ())); + + // Free up the memory block. + mb->release (); + + // Now try the send()/recv() interface. + char mytext[] = "This string is sent by peer1 as buffer"; + + ACE_ERROR ((LM_ERROR, + "(%t) peer1 sending text\n")); + if (c_stream.send (mytext, sizeof mytext) == -1) + ACE_ERROR ((LM_ERROR, + "(%t) buffer send from peer1 failed\n")); + + char conbuf[30]; // Buffer to receive response. + + int i = 0; + + for (char c = ' '; c != '!'; i++) + { + if (c_stream.recv (&c, 1) == -1) + ACE_ERROR ((LM_ERROR, + "(%t) buffer recv from peer1 failed\n")); + else + conbuf[i] = c; + } + + conbuf[i] = '\0'; + ACE_DEBUG ((LM_DEBUG, + "(%t) peer1 received buffer with \"%s\"\n", + conbuf)); + c_stream.close (); + return 0; +} + +static void * +peer2 (void *) +{ + ACE_UPIPE_Acceptor acc (addr); + ACE_UPIPE_Stream s_stream; + + // Spawn a peer1 thread. + if (ACE_Thread_Manager::instance ()->spawn (ACE_THR_FUNC (peer1), + (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "spawn"), + 0); + + ACE_DEBUG ((LM_DEBUG, + "(%t) peer2 starting accept\n")); + + if (acc.accept (s_stream) == -1) + ACE_ERROR ((LM_ERROR, + "(%t) ACE_UPIPE_Acceptor.accept failed\n")); + + ACE_Message_Block *mb = 0; + + if (s_stream.recv (mb) == -1) + ACE_ERROR ((LM_ERROR, + "(%t) peer2 recv failed\n")); + + ACE_DEBUG ((LM_DEBUG, "(%t) peer2 recv is \"%s\"\n", + mb->rd_ptr ())); + + mb->wr_ptr (mb->rd_ptr ()); + mb->copy ("thanks", 7); + + if (s_stream.send (mb) == -1) + ACE_ERROR ((LM_ERROR, + "(%t) peer2 send failed\n")); + + char s_buf[42]; + ACE_DEBUG ((LM_DEBUG, + "(%t) peer2 sleeping on recv\n")); + + if (s_stream.recv (s_buf, sizeof s_buf) == -1) + ACE_ERROR ((LM_ERROR, + "(%t) peer2 recv failed\n")); + else + ACE_DEBUG ((LM_DEBUG, + "(%t) peer2 received buffer with \"%s\"\n", + s_buf)); + + ACE_OS::strcpy (s_buf, + "this is the peer2 response!"); + + if (s_stream.send (s_buf, 30) == -1) + ACE_ERROR ((LM_ERROR, + "(%t) peer2 send failed\n")); + s_stream.close (); + return 0; +} + +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + // Spawn a peer2 thread. + if (ACE_Thread_Manager::instance ()->spawn (ACE_THR_FUNC (peer2), + (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "spawn"), + 1); + // Wait for peer2 and peer1 threads to exit. + ACE_Thread_Manager::instance ()->wait (); + return 0; +} +#else +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "threads not supported on this platform\n"), + -1); +} +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/IPC_SAP/UPIPE_SAP/ex2.cpp b/ACE/examples/IPC_SAP/UPIPE_SAP/ex2.cpp new file mode 100644 index 00000000000..e19a83460ce --- /dev/null +++ b/ACE/examples/IPC_SAP/UPIPE_SAP/ex2.cpp @@ -0,0 +1,179 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// examples +// +// = FILENAME +// ex2.cpp +// +// = DESCRIPTION +// Example for using <ACE_UPIPE_SAP> and <ACE_Thread> for +// intra-process communication. +// +// = AUTHOR +// Gerhard Lenzer and Douglas C. Schmidt +// +// ============================================================================ + +#include "ace/OS_main.h" +#include "ace/UPIPE_Connector.h" +#include "ace/UPIPE_Acceptor.h" +#include "ace/Auto_Ptr.h" +#include "ace/OS_NS_time.h" + +ACE_RCSID(UPIPE_SAP, ex2, "$Id$") + +#if defined (ACE_HAS_THREADS) + +// Data for testsuite. +static int size = 0; +static int iterations = 0; + +static void * +supplier (void *) +{ + ACE_UPIPE_Stream s_stream; + + ACE_UPIPE_Addr c_addr (ACE_TEXT("pattern")); + + ACE_Auto_Basic_Array_Ptr<char> mybuf (new char[size]); + + for (int i = 0; i < size; i++) + mybuf[i] = 'a'; + + ACE_DEBUG ((LM_DEBUG, + "(%t) supplier starting connect thread\n")); + + ACE_UPIPE_Connector con; + + if (con.connect (s_stream, c_addr) == -1) + ACE_ERROR ((LM_ERROR, + "(%t) %p\n", + "ACE_UPIPE_Acceptor.connect failed")); + + // Test asynchronicity (the "acausal principle" ;-)). + s_stream.enable (ACE_SIGIO); + + ACE_Message_Block *mb_p; + + for (int j = 0; j < iterations; j++) + { + ACE_NEW_RETURN (mb_p, + ACE_Message_Block (size, + ACE_Message_Block::MB_DATA, + (ACE_Message_Block *) 0, + mybuf.get ()), + 0); + if (s_stream.send (mb_p) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "(%t) %p\n", + "send failed"), + 0); + } + + ACE_NEW_RETURN (mb_p, + ACE_Message_Block ((size_t) 0), + 0); + + // Insert a 0-sized message block to signal the other side to shut + // down. + if (s_stream.send (mb_p) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "(%t) %p\n", + "send failed"), + 0); + s_stream.close (); + return 0; +} + +static void * +consumer (void *) +{ + ACE_UPIPE_Stream c_stream; + + // Set the high water mark to size to achieve optimum performance. + + int wm = size * iterations; + + if (c_stream.control (ACE_IO_Cntl_Msg::SET_HWM, + &wm) == -1) + ACE_DEBUG ((LM_DEBUG, + "set HWM failed\n")); + + ACE_UPIPE_Addr serv_addr (ACE_TEXT("pattern")); + + // accept will wait up to 4 seconds + ACE_UPIPE_Acceptor acc (serv_addr); + + ACE_DEBUG ((LM_DEBUG, + "(%t) consumer spawning the supplier thread\n")); + + // Spawn the supplier thread. + if (ACE_Thread_Manager::instance ()->spawn (ACE_THR_FUNC (supplier), + (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "spawn"), + 0); + + ACE_DEBUG ((LM_DEBUG, + "(%t) consumer starting accept\n")); + + if (acc.accept (c_stream) == -1) + ACE_ERROR ((LM_ERROR, + "(%t) %p\n", + "ACE_UPIPE_Acceptor.accept failed")); + + // Time measurement. + time_t currsec; + ACE_OS::time (&currsec); + time_t start = (time_t) currsec; + + int received_messages = 0; + + for (ACE_Message_Block *mb = 0; + c_stream.recv (mb) != -1 && mb->size () != 0; + mb->release ()) + received_messages++; + + ACE_OS::time (&currsec); + time_t secs = (time_t) currsec - start; + + ACE_DEBUG ((LM_DEBUG, + "(%t) Transferred %d blocks of size %d\n" + "The program ran %d seconds\n", + received_messages, size, secs)); + c_stream.close (); + return 0; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + size = argc > 1 ? ACE_OS::atoi (argv[1]) : 32; + iterations = argc > 2 ? ACE_OS::atoi (argv[2]) : 16; + + // Spawn the two threads. + if (ACE_Thread_Manager::instance ()->spawn (ACE_THR_FUNC (consumer), + (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "spawn"), + 1); + // Wait for producer and consumer threads to exit. + ACE_Thread_Manager::instance ()->wait (); + return 0; +} +#else +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "threads not supported on this platform\n"), + 0); +} +#endif /* ACE_HAS_THREADS */ diff --git a/ACE/examples/IPC_SAP/UPIPE_SAP/ex3.cpp b/ACE/examples/IPC_SAP/UPIPE_SAP/ex3.cpp new file mode 100644 index 00000000000..57ff4f34d9e --- /dev/null +++ b/ACE/examples/IPC_SAP/UPIPE_SAP/ex3.cpp @@ -0,0 +1,159 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// examples +// +// = FILENAME +// ex3.cpp +// +// = DESCRIPTION +// Example for using <ACE_UPIPE_SAP> and <ACE_Thread> for intra-process +// communication. This example uses char buffers as input/output +// interface to the <ACE_UPIPE_Stream>. +// +// = AUTHOR +// Gerhard Lenzer and Prashant Jain. +// +// ============================================================================ + +#include "ace/OS_main.h" +#include "ace/UPIPE_Connector.h" +#include "ace/UPIPE_Acceptor.h" +#include "ace/Auto_Ptr.h" +#include "ace/OS_NS_time.h" + +ACE_RCSID(UPIPE_SAP, ex3, "$Id$") + +#if defined (ACE_HAS_THREADS) + +// Data for testsuite. +static int size = 0; +static int iterations = 0; + +static void * +supplier (void *) +{ + ACE_UPIPE_Stream s_stream; + ACE_UPIPE_Addr c_addr (ACE_TEXT("pattern")); + + ACE_UPIPE_Connector con; + + ACE_DEBUG ((LM_DEBUG, + "(%t) supplier starting connect thread\n")); + + if (con.connect (s_stream, c_addr) == -1) + ACE_ERROR ((LM_ERROR, + "(%t) %p\n", + "ACE_UPIPE_Acceptor.connect failed")); + + ACE_Auto_Basic_Array_Ptr<char> mybuf (new char[size]); + + for (int i = 0; i < size; i++) + mybuf[i] = 'a'; + + for (int j = 0; j < iterations; j++) + if (s_stream.send (mybuf.get (), size) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "(%t) %p\n", "send failed"), + 0); + + // Insert a 0-sized message block to signal the other side to shut + // down. + if (s_stream.send (new ACE_Message_Block ((size_t) 0)) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "(%t) %p\n", "error put"), + 0); + s_stream.close (); + return 0; +} + +static void * +consumer (void *) +{ + ACE_UPIPE_Stream c_stream; + ACE_UPIPE_Addr serv_addr (ACE_TEXT("pattern")); + + // Accept will wait up to 4 seconds + ACE_UPIPE_Acceptor acc (serv_addr); + + ACE_DEBUG ((LM_DEBUG, + "(%t) consumer spawning the supplier thread\n")); + + // Spawn the supplier thread. + if (ACE_Thread_Manager::instance ()->spawn (ACE_THR_FUNC (supplier), + (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "spawn"), + 0); + ACE_DEBUG ((LM_DEBUG, + "(%t) consumer starting accept\n")); + + if (acc.accept (c_stream) == -1) + ACE_ERROR ((LM_ERROR, "(%t) %p\n", + "ACE_UPIPE_Acceptor.accept failed")); + + // Ensure deletion upon exit. + ACE_Auto_Basic_Array_Ptr<char> mybuf (new char[size]); + time_t currsec; + + ACE_OS::time (&currsec); + + time_t start = (time_t) currsec; + int result = 0; + int blocks = 0; + + for (;; blocks++) + { + result = c_stream.recv (mybuf.get (), size); + if (result <= 0) + break; + } + + if (result == -1) + ACE_ERROR ((LM_ERROR, + "(%t) %p\n", "recv failed")); + + ACE_OS::time (&currsec); + time_t secs = (time_t) currsec - start; + + ACE_DEBUG ((LM_DEBUG, + "(%t) Transferred %d blocks of size %d\n" + "The program ran %d seconds\n", + blocks, + size, + secs)); + c_stream.close (); + return 0; +} + +int +ACE_TMAIN (int argc, ACE_TCHAR *argv[]) +{ + size = argc > 1 ? ACE_OS::atoi (argv[1]) : 32; + iterations = argc > 2 ? ACE_OS::atoi (argv[2]) : 16; + + // Spawn the thread. + if (ACE_Thread_Manager::instance ()->spawn (ACE_THR_FUNC (consumer), + (void *) 0, + THR_NEW_LWP | THR_DETACHED) == -1) + ACE_ERROR_RETURN ((LM_ERROR, + "%p\n", + "spawn"), + 1); + // Wait for producer and consumer threads to exit. + ACE_Thread_Manager::instance ()->wait (); + return 0; +} +#else +int +ACE_TMAIN (int, ACE_TCHAR *[]) +{ + ACE_ERROR_RETURN ((LM_ERROR, + "threads not supported on this platform\n"), + 0); +} +#endif /* ACE_HAS_THREADS */ |