diff options
author | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-08-30 22:18:03 +0000 |
---|---|---|
committer | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-08-30 22:18:03 +0000 |
commit | a479078c9f8ff4c0c17c679468298f61c19230d9 (patch) | |
tree | c185e1bc56840640bb1944f776499c6ffaa1dc0f /docs/tutorials/001 | |
parent | dd4501a0f6706b945705b7640d212ef444c3c68e (diff) | |
download | ATCD-pre_pluggable_av_merge.tar.gz |
This commit was manufactured by cvs2svn to create tagpre_pluggable_av_merge
'pre_pluggable_av_merge'.
Diffstat (limited to 'docs/tutorials/001')
-rw-r--r-- | docs/tutorials/001/001.dsp | 108 | ||||
-rw-r--r-- | docs/tutorials/001/00SetEnv | 2 | ||||
-rw-r--r-- | docs/tutorials/001/Makefile | 76 | ||||
-rw-r--r-- | docs/tutorials/001/acceptor.h | 128 | ||||
-rw-r--r-- | docs/tutorials/001/combine.shar | 574 | ||||
-rw-r--r-- | docs/tutorials/001/logger.h | 178 | ||||
-rw-r--r-- | docs/tutorials/001/page01.html | 102 | ||||
-rw-r--r-- | docs/tutorials/001/page02.html | 172 | ||||
-rw-r--r-- | docs/tutorials/001/page03.html | 195 | ||||
-rw-r--r-- | docs/tutorials/001/page04.html | 211 | ||||
-rw-r--r-- | docs/tutorials/001/page05.html | 54 | ||||
-rw-r--r-- | docs/tutorials/001/server.cpp | 79 | ||||
-rw-r--r-- | docs/tutorials/001/simple.fig | 57 | ||||
-rw-r--r-- | docs/tutorials/001/simple.gif | bin | 6040 -> 0 bytes |
14 files changed, 0 insertions, 1936 deletions
diff --git a/docs/tutorials/001/001.dsp b/docs/tutorials/001/001.dsp deleted file mode 100644 index 196a498962a..00000000000 --- a/docs/tutorials/001/001.dsp +++ /dev/null @@ -1,108 +0,0 @@ -# Microsoft Developer Studio Project File - Name="001" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=001 - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "001.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "001.mak" CFG="001 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "001 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "001 - Win32 Debug" (based on "Win32 (x86) Console Application")
-!MESSAGE
-
-# Begin Project
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "001 - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 ace.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\ace"
-
-!ELSEIF "$(CFG)" == "001 - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MDd /W3 /GX /Od /I "..\..\.." /D "WIN32" /D "_DEBUG" /YX /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 aced.lib /nologo /subsystem:console /debug /machine:I386 /out:"server.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "001 - Win32 Release"
-# Name "001 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\server.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=.\acceptor.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\logger.h
-# End Source File
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff --git a/docs/tutorials/001/00SetEnv b/docs/tutorials/001/00SetEnv deleted file mode 100644 index eca78e10c85..00000000000 --- a/docs/tutorials/001/00SetEnv +++ /dev/null @@ -1,2 +0,0 @@ -export ACE_ROOT=/local/src/ACE/ACE_wrappers -export LD_LIBRARY_PATH=$ACE_ROOT/ace:$LD_LIBRARY_PATH diff --git a/docs/tutorials/001/Makefile b/docs/tutorials/001/Makefile deleted file mode 100644 index 8c465a2faf4..00000000000 --- a/docs/tutorials/001/Makefile +++ /dev/null @@ -1,76 +0,0 @@ -#---------------------------------------------------------------------------- -# $Id$ -# -# Makefile for the Reactor Server Logging Daemon -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = server - -FILES = - -LSRC = $(addsuffix .cpp,$(FILES)) -LOBJ = $(addsuffix .o,$(FILES)) -SHOBJ = $(addsuffix .so,$(FILES)) - -LDLIBS = $(addprefix .shobj/,$(SHOBJ)) - -VLDLIBS = $(LDLIBS:%=%$(VAR)) - -BUILD = $(VBIN) - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - -# In order to make the generation of HTML pages from sourcecode -# easier, I've started putting the comments into *.pre and *.pst files. -# Those are then combined (via the perl script "combine") with the -# source code to create the HTMLs. In an effort to declutter the -# directory, I archive the component files in a shell-archive (eg -- -# shar) file that is commited to the repository. - -# Invoke the combine script to pull together the pre-code comments, -# code and post-code comments that makeup a tutorial page. 'combine' -# keys itself off of the *.pre files to know what it should build. An -# accessory file "bodies" specifies which source files comprise the -# body of each tutorial page. -HTML : # - [ -f hdr ] || $(MAKE) UNSHAR - perl ../combine *.pre ; chmod +r *.html - -# The SHAR target simply invokes "shar" to create the shell archive. -# It is important to include all "component" files in the shar command -# line so that they will be included in the archive. It is not -# necessary to include the source code files since they're commited as-is. -SHAR : # - [ ! -f combine.shar ] || exit 1 - shar -T hdr bodies *.pre *.pst > combine.shar && $(RM) hdr bodies *.pre *.pst - -# For orthogonality, we have an UNSHAR to match SHAR. -UNSHAR : # - sh combine.shar - -CLEAN : realclean - $(RM) hdr bodies *.pre *.pst .depend - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - -.obj/server.o .shobj/server.so: server.cpp acceptor.h logger.h - diff --git a/docs/tutorials/001/acceptor.h b/docs/tutorials/001/acceptor.h deleted file mode 100644 index d44433bb233..00000000000 --- a/docs/tutorials/001/acceptor.h +++ /dev/null @@ -1,128 +0,0 @@ -// $Id$ - -#ifndef _CLIENT_ACCEPTOR_H -#define _CLIENT_ACCEPTOR_H - -/* A SOCK_Acceptor knows how to accept socket connections. We'll use - one of those at the heart of our Logging_Acceptor. */ -#include "ace/SOCK_Acceptor.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/* An Event_Handler is what you register with ACE_Reactor. When - events occur, the reactor will callback on the Event_Handler. More - on that in a few lines. */ -#include "ace/Event_Handler.h" - -/* When a client connects, we'll create a Logging_Handler to deal with - the connection. Here, we bring in that declaration. */ -#include "logger.h" - -/* Our Logging_Acceptor is derived from ACE_Event_Handler. That lets - the reactor treat our acceptor just like every other handler. */ -class Logging_Acceptor : public ACE_Event_Handler -{ -public: - - /* For this simple case we won't bother with either constructor or - destructor. In a real application you would certainly have them. */ - - /* Here's the open() method we called from main(). We have two - things to accomplish here: (1) Open the acceptor so that we can - hear client requests and (2) register ourselves with the reactor - so that we can respond to those requests. */ - int open (const ACE_INET_Addr &addr, - ACE_Reactor *reactor) - { - /* Perform the open() on the acceptor. We pass through the - address at which main() wants us to listen. The second - parameter tells the acceptor it is OK to reuse the address. - This is necessary sometimes to get around closed connections - that haven't timed out. */ - if (this->peer_acceptor_.open (addr, 1) == -1) - return -1; - - /* Remember the reactor we're using. We'll need it later when we - create a client connection handler. */ - reactor_ = reactor; - - /* Now we can register with the reactor we were given. Since the - reactor pointer is global, we could have just used that but it's - gross enough already. Notice that we can pass 'this' right into - the registration since we're derived from ACE_Event_Handler. We - also provide ACCEPT_MASK to tell the reactor that we want to - know about accept requests from clients. */ - return reactor->register_handler (this, - ACE_Event_Handler::ACCEPT_MASK); - } - -private: - - /* To provide multi-OS abstraction, ACE uses the concept of - "handles" for connection endpoints. In Unix, this is a - traditional file descriptor (or integer). On other OS's, it may - be something else. The reactor will need to get the handle (file - descriptor) to satisfy it's own internal needs. Our relevant - handle is the handle of the acceptor object, so that's what we - provide. */ - ACE_HANDLE get_handle (void) const - { - return this->peer_acceptor_.get_handle (); - } - - /* When an accept request arrives, the reactor will invoke the - handle_input() callback. This is where we deal with the - connection request. */ - virtual int handle_input (ACE_HANDLE handle) - { - /* The handle provided to us by the reactor is the one that - triggered our up-call. In some advanced situations, you might - actually register a single handler for multiple connections. - The _handle parameter is a way to sort 'em out. Since we don't - use that here, we simply ignore the parameter with the - ACE_UNUSED_ARG() macro. */ - ACE_UNUSED_ARG (handle); - - Logging_Handler *svc_handler; - - /* In response to the connection request, we create a new - Logging_Handler. This new object will be used to interact with - the client until it disconnects. Note how we use the - ACE_NEW_RETURN macro, which returns -1 if operator new fails. */ - ACE_NEW_RETURN (svc_handler, - Logging_Handler, - -1); - - /* To complete the connection, we invoke the accept() method call - on the acceptor object and provide it with the connection - handler instance. This transfers "ownership" of the connection - from the acceptor to the connection handler. */ - if (this->peer_acceptor_.accept (*svc_handler) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p", - "accept failed"), - -1); - - /* Again, most objects need to be open()ed before they are useful. - We'll give the handler our reactor pointer so that it can - register for events as well. If the open fails, we'll force a - close(). */ - if (svc_handler->open (reactor_) == -1) - svc_handler->close (); - - return 0; - } - -protected: - - /* Our acceptor object instance */ - ACE_SOCK_Acceptor peer_acceptor_; - - /* A place to remember our reactor pointer */ - ACE_Reactor *reactor_; -}; - -#endif /* _CLIENT_ACCEPTOR_H */ - diff --git a/docs/tutorials/001/combine.shar b/docs/tutorials/001/combine.shar deleted file mode 100644 index 8dcf0ab3f72..00000000000 --- a/docs/tutorials/001/combine.shar +++ /dev/null @@ -1,574 +0,0 @@ -#!/bin/sh -# This is a shell archive (produced by GNU sharutils 4.2). -# To extract the files from this archive, save it to some FILE, remove -# everything before the `!/bin/sh' line above, then type `sh FILE'. -# -# Made on 1999-01-17 14:14 EST by <jcej@chiroptera.tragus.org>. -# Source directory was `/var/home/jcej/projects/ACE_wrappers/docs/tutorials/001'. -# -# Existing files will *not* be overwritten unless `-c' is specified. -# -# This shar contains: -# length mode name -# ------ ---------- ------------------------------------------ -# 524 -rw-rw-r-- hdr -# 38 -rw-rw-r-- bodies -# 4034 -rw-rw-r-- page01.pre -# 2188 -rw-rw-r-- page02.pre -# 553 -rw-rw-r-- page03.pre -# 79 -rw-rw-r-- page04.pre -# 1149 -rw-rw-r-- page05.pre -# 478 -rw-rw-r-- page02.pst -# 1434 -rw-rw-r-- page03.pst -# 279 -rw-rw-r-- page04.pst -# -save_IFS="${IFS}" -IFS="${IFS}:" -gettext_dir=FAILED -locale_dir=FAILED -first_param="$1" -for dir in $PATH -do - if test "$gettext_dir" = FAILED && test -f $dir/gettext \ - && ($dir/gettext --version >/dev/null 2>&1) - then - set `$dir/gettext --version 2>&1` - if test "$3" = GNU - then - gettext_dir=$dir - fi - fi - if test "$locale_dir" = FAILED && test -f $dir/shar \ - && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) - then - locale_dir=`$dir/shar --print-text-domain-dir` - fi -done -IFS="$save_IFS" -if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED -then - echo=echo -else - TEXTDOMAINDIR=$locale_dir - export TEXTDOMAINDIR - TEXTDOMAIN=sharutils - export TEXTDOMAIN - echo="$gettext_dir/gettext -s" -fi -touch -am 1231235999 $$.touch >/dev/null 2>&1 -if test ! -f 1231235999 && test -f $$.touch; then - shar_touch=touch -else - shar_touch=: - echo - $echo 'WARNING: not restoring timestamps. Consider getting and' - $echo "installing GNU \`touch', distributed in GNU File Utilities..." - echo -fi -rm -f 1231235999 $$.touch -# -if mkdir _sh00080; then - $echo 'x -' 'creating lock directory' -else - $echo 'failed to create lock directory' - exit 1 -fi -# ============= hdr ============== -if test -f 'hdr' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'hdr' '(file already exists)' -else - $echo 'x -' extracting 'hdr' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'hdr' && -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> -<HTML> -<HEAD> -X <TITLE>ACE Tutorial 001</TITLE> -X <META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (Win95; I) [Netscape]"> -X <META NAME="Author" CONTENT="James CE Johnson"> -X <META NAME="Description" CONTENT="A first step towards using ACE productively"> -</HEAD> -<BODY text = "#000000" link="#000fff" vlink="#ff0f0f" bgcolor="#ffffff"> -X -X -<CENTER><P><B><FONT SIZE=+2>ACE Tutorial 001<BR> -A Beginners Guide to Using the ACE Toolkit</FONT></B></P></CENTER> -X -<hr> -SHAR_EOF - $shar_touch -am 0117141099 'hdr' && - chmod 0664 'hdr' || - $echo 'restore of' 'hdr' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'hdr:' 'MD5 check failed' -1d643c1c0995e071a0a9e3662d7a440b hdr -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" - test 524 -eq "$shar_count" || - $echo 'hdr:' 'original size' '524,' 'current size' "$shar_count!" - fi -fi -# ============= bodies ============== -if test -f 'bodies' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'bodies' '(file already exists)' -else - $echo 'x -' extracting 'bodies' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'bodies' && -PAGE=2 -server.cpp -acceptor.h -logger.h -SHAR_EOF - $shar_touch -am 0117140699 'bodies' && - chmod 0664 'bodies' || - $echo 'restore of' 'bodies' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'bodies:' 'MD5 check failed' -20ddb6c1ff71a6481ce0956f1a70a612 bodies -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" - test 38 -eq "$shar_count" || - $echo 'bodies:' 'original size' '38,' 'current size' "$shar_count!" - fi -fi -# ============= page01.pre ============== -if test -f 'page01.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page01.pre' '(file already exists)' -else - $echo 'x -' extracting 'page01.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page01.pre' && -<P>The purpose of this tutorial is to show you how to create a very simple -server capable of handling multiple client connections. Unlike a "traditional" -server application, this one handles all requests in one process. Issues -of multi-processing and multi-threading will be handled in later tutorials.</P> -X -<P> -<HR WIDTH="100%"></P> -X -<P>What do you need to create a server?</P> -X -<OL> -<LI>Something which accepts connections from clients</LI> -X -<LI>Something which handles established connections</LI> -X -<LI>A main program loop that handles it all</LI> -</OL> -X -<P>The ACE Acceptor provides a solution for our first requirement. -This class is given a TCP/IP port number on which it will listen for -incoming connections. When a connection is attempted, the acceptor will -create a new object (the handler) to deal with the client connection while -the acceptor goes back to listening for other connections.</P> -X -<P>The ACE EventHandler solves our second requirement. This doesn't -seem obvious now but as we progress through this tutorial it will become -more clear.</P> -X -<P>Finally, a simple <I>main()</I> function will provide our program loop. -After any program initialization, it will enter an infinite loop which -waits for connection attempts to the Acceptor or data "events" -on the EventHandler.</P> -X -<P> -<HR WIDTH="100%"></P> -X -<P>Before we continue, I need to introduce one more ACE concept: the Reactor. -</P> -X -<P>I don't want to go into great detail at this time on what the Reactor -is, what it does and how it does it but it is necessary for you to understand -the basic function of a reactor because it is going to be in the first -piece of code you see. The figure below depicts the interrelationships -between the Reactor, the Acceptor and the application handler.</P> -<P> <center> <img src="simple.gif" align=center> </center> -X -<P>Briefly:<BR> -The reactor is an object which reacts when things happen to other objects. -These things are called <I>events</I>. The <I>other objects</I> are communications -objects which you have <I>registered</I> with the reactor. At the time -of registration, you also specify which events you are interested in. The -reactor is notified by the operating system when the events of interest -occur within the registered objects. The reactor then uses member functions -of the registered object to process the event. Notice that the reactor -doesn't care what happens because of the event. It is the object's responsibility -to process the event correctly. The reactor simply notifies the object -of the event.</P> -X -<P>Why use the reactor?</P> -X -<P>That will become clear as the tutorial progresses. For now, however, -a brief answer would be this: it allows multiple simultaneous client connections -to be processed efficiently by a single-threaded server. </P> -X -<P>Servers have traditionally created a separate thread or process for -each client served. For large-volume services (such as telnet and ftp) -this is appropriate. However, for small-volume services the overhead of -process creation far outweighs the actual work being done. So... folks -begin using threads instead of processes to handle the clients. This is -good also but still, in some cases, the overhead is too much to bear. Instead, -why not have a single thread handle several clients and use a more intelligent -load-balancing methodology than one-thread-or-process-per-client? -<i>Caveat: Handling all requests in one thread of one process is really -only good when the requests can be handled almost instantaneously.</i> -</P> -X -<P>This is where the reactor's power and flexibility come into play. The -developer can create a simple, single-threaded application that is later -modified to thread-per-client, process-per-client or thread-pool solution. -<P> -If all of this is gibberish and makes you think that ACE is way to hard to -learn, don't worry. We'll go into all the details and explain as we go. -I only went into all of this so that it can kick around in the back of your -mind until you need it later. -<P> -SHAR_EOF - $shar_touch -am 0117140899 'page01.pre' && - chmod 0664 'page01.pre' || - $echo 'restore of' 'page01.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page01.pre:' 'MD5 check failed' -58b12a93efda94c99be5d0b38c3096a5 page01.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" - test 4034 -eq "$shar_count" || - $echo 'page01.pre:' 'original size' '4034,' 'current size' "$shar_count!" - fi -fi -# ============= page02.pre ============== -if test -f 'page02.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page02.pre' '(file already exists)' -else - $echo 'x -' extracting 'page02.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page02.pre' && -<P>From here, we to move on to the main program loop. In a way, we're -starting at the final product when we do this, but it is a very simple -piece of code and a good place to start. -X -<P>The <A HREF="server.cpp">main</A> -program is really quite simple. The real work is done in the ACE derived -classes. -X -<P> -Kirthika Parameswaran offers this abstract of Tutorial 1: -<UL> -<P> -This is a simple logging server example. -The Reactor is used to handle more than one client request using a -single thread of execution instead of one thread per client. The Reactor -reactes to events and demultiplexes the events to the appropriate -Event_Handler registered with it, using the "callback" technique. The -reactor runs in an infinte event loop handling all the incoming events. -<P> -The Logging_Acceptor listens at a SERVER PORT address and passively -waits for requests to arrive. The Acceptor is also an Event_Handler and -is registered with the Reactor. This way it is simply yet another -Event_Handler for the Reactor and hence no special processing is needed -for it. -<P> -Once a connection request occurs, the Acceptor accepts it and -a connection is established. The reactor instance is passed to the -handler so that it can register with the Reactor. It does so with an -ACE_Event_Handler::ACCEPT_MASK. -<P> -The Logging_Client is another Event_Handler which actually handles the -client requests in its handle_input() method. It is also registered -with the Reactor with the ACE_Event_Handler::READ_MASK. -<P> -The Event_Handlers can be unregistered from the Reactor using -handle_close() methods -or explicitly calling the remove_handler() methods. -<P> -This server application builds and executes succesfully waiting for -client requests to arrive. -<P> -</UL> -FYI (from Doug): -<UL> -The ACCEPT_MASK is defined in the ACE_Event_Handler class. It's used -to inform the Reactor that you want to register an event handler to -"accept" a connection passively. Not surprisingly, the ACE_Acceptor -component uses this. -<P> -The READ_MASK is also defined in the ACE_Event_Handler class. It's -used to inform the Reactor that you want to register an event handler -to "read" data from an established connection. -</UL> -<hr> -SHAR_EOF - $shar_touch -am 0117140999 'page02.pre' && - chmod 0664 'page02.pre' || - $echo 'restore of' 'page02.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page02.pre:' 'MD5 check failed' -5e23294cf842366a9ca1b14867856359 page02.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`" - test 2188 -eq "$shar_count" || - $echo 'page02.pre:' 'original size' '2188,' 'current size' "$shar_count!" - fi -fi -# ============= page03.pre ============== -if test -f 'page03.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page03.pre' '(file already exists)' -else - $echo 'x -' extracting 'page03.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page03.pre' && -<P>Now we begin to look at the <A HREF="acceptor.h">acceptor</A> object. -X -<P> -Kirthika has this analogy: -<P> -<UL> -Consider an office: -<P> -Reactor: Receptionist -<P> -Event_Handlers: various Departments catering to specific needs. -<P> -SERVER_PORT: door -<P> -Acceptor: Doorkeeper -<P> -Thus when a needy person (client) enters the open door (port) -maintained by the doorkeeper (acceptor waiting for connection -request), the receptionist(reactor) directs the person towards the -appropriate section (event_handler) which would cater to his needs. -</UL> -<P> -<HR> -SHAR_EOF - $shar_touch -am 0117140999 'page03.pre' && - chmod 0664 'page03.pre' || - $echo 'restore of' 'page03.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page03.pre:' 'MD5 check failed' -b1eca88136f15c2c1156a2602daaff7e page03.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`" - test 553 -eq "$shar_count" || - $echo 'page03.pre:' 'original size' '553,' 'current size' "$shar_count!" - fi -fi -# ============= page04.pre ============== -if test -f 'page04.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page04.pre' '(file already exists)' -else - $echo 'x -' extracting 'page04.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page04.pre' && -<P>Now we begin to look at the <A HREF="logger.h">logger</A> -object. -X -<P> -<HR> -SHAR_EOF - $shar_touch -am 0117140999 'page04.pre' && - chmod 0664 'page04.pre' || - $echo 'restore of' 'page04.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page04.pre:' 'MD5 check failed' -ea4861a868e3dce3607602f1ce35b7fa page04.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`" - test 79 -eq "$shar_count" || - $echo 'page04.pre:' 'original size' '79,' 'current size' "$shar_count!" - fi -fi -# ============= page05.pre ============== -if test -f 'page05.pre' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page05.pre' '(file already exists)' -else - $echo 'x -' extracting 'page05.pre' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page05.pre' && -<P>This concludes the first tutorial on using ACE. We've learned how to -create a simple server without knowing very much about network programming. -X -<P>The code used in this tutorial is for illustration purposes. That means -it may or may not work. Actually, it <I>does</I> work but the -astute reader will notice a number of places for potential memory leaks. -We'll work on cleaning those up in future tutorials but if you find one -feel free to send me a fix and I'll integrate it into the tutorial. -X -<UL> -<LI> -<A HREF="00SetEnv">Environment -Settings</A></LI> -X -<LI> -<A HREF="Makefile">Makefile</A></LI> -X -<LI> -<A HREF="server.cpp">main -program</A></LI> -X -<LI> -<A HREF="acceptor.h">acceptor -object</A></LI> -X -<LI> -<A HREF="logger.h">connection -handler</A></LI> -</UL> -X -<P> -To read more about the patterns used in this example (as well as -quite a few which aren't!), you should check out -<A HREF="http://www.cs.wustl.edu/~schmidt/patterns-ace.html">http://www.cs.wustl.edu/~schmidt/patterns-ace.html.</A> -In fact, it's probably safe to say that the concepts found there will keep -coming back to haunt you as these tutorials continue. -<P> -SHAR_EOF - $shar_touch -am 0117141399 'page05.pre' && - chmod 0664 'page05.pre' || - $echo 'restore of' 'page05.pre' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page05.pre:' 'MD5 check failed' -7d00b8c59c4f7210634bc5fdb75dfbcc page05.pre -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`" - test 1149 -eq "$shar_count" || - $echo 'page05.pre:' 'original size' '1149,' 'current size' "$shar_count!" - fi -fi -# ============= page02.pst ============== -if test -f 'page02.pst' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page02.pst' '(file already exists)' -else - $echo 'x -' extracting 'page02.pst' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page02.pst' && -<HR WIDTH="100%"> -X -<P>As I said, the main program is really quite simple: -<UL> -<LI> -Create an address for the <I>port</I> we want to listen to</LI> -X -<LI> -Create an acceptor which listens on that address</LI> -X -<LI> -Register the acceptor with a reactor to respond to the connection requests</LI> -X -<LI> -Enter an infinite loop to let the reactor handle the events</LI> -</UL> -On the next page, we will take a look at the acceptor and how it responds -to new connection requests. -X -<P> -SHAR_EOF - $shar_touch -am 0117141299 'page02.pst' && - chmod 0664 'page02.pst' || - $echo 'restore of' 'page02.pst' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page02.pst:' 'MD5 check failed' -51b1f08eabda5789182b566fdb7756fe page02.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pst'`" - test 478 -eq "$shar_count" || - $echo 'page02.pst:' 'original size' '478,' 'current size' "$shar_count!" - fi -fi -# ============= page03.pst ============== -if test -f 'page03.pst' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page03.pst' '(file already exists)' -else - $echo 'x -' extracting 'page03.pst' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page03.pst' && -<HR WIDTH="100%"></PRE> -It is important to notice here that we have done very little application-specifc -code in developing this object. In fact, if we take out the progress information, -the only app-specific code is when we create the new <I>Logging_Handler</I> -object to give to the <I>accept</I> function. You may begin to wonder why -there isn't a C++ template that does all of this coding for you. Actually, -the ACE toolkit happens to have one handy: -<UL>typedef ACE_Acceptor <<I>YourHandlerClass</I>, ACE_SOCK_ACCEPTOR> -<I>YourAcceptorClass</I>;</UL> -We would have used it like this: -<UL>typedef ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR> Client_Acceptor;</UL> -This will create a piece of code similar to what I've shown above. The -primary difference is that the <I>handle_input </I>function created by -the template does NOT register the handler with the reactor. In the long-run, -that is good for us because we can then move that logic into the <I>open</I> -function of the <I>Logging_Handler</I> and use a completely-generic acceptor. -X -<P>Now that we know how to accept a connection request, let's move on to -the next page where we learn how to handle the actual connection. Even -though we just learned about this cool template thing, we will continue -to use the "hand-written" acceptor developed above. As I mentioned, the -only difference will be in the <I>open</I> function of the connection handler -anyway. -X -<P> -SHAR_EOF - $shar_touch -am 0117141299 'page03.pst' && - chmod 0664 'page03.pst' || - $echo 'restore of' 'page03.pst' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page03.pst:' 'MD5 check failed' -7a18def18c6a83a1015e08f63b5868be page03.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pst'`" - test 1434 -eq "$shar_count" || - $echo 'page03.pst:' 'original size' '1434,' 'current size' "$shar_count!" - fi -fi -# ============= page04.pst ============== -if test -f 'page04.pst' && test "$first_param" != -c; then - $echo 'x -' SKIPPING 'page04.pst' '(file already exists)' -else - $echo 'x -' extracting 'page04.pst' '(text)' - sed 's/^X//' << 'SHAR_EOF' > 'page04.pst' && -<HR WIDTH="100%"> -X -<P> -The comments really should tell the story. The really -interesting stuff is in <i>handle_input()</i>. Everything -else is just housekeeping. -In the future, we'll learn about ACE_Svc_Handler<> -which will take care of most of the housekeeping for us. -<P> -SHAR_EOF - $shar_touch -am 0117141299 'page04.pst' && - chmod 0664 'page04.pst' || - $echo 'restore of' 'page04.pst' 'failed' - if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \ - && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then - md5sum -c << SHAR_EOF >/dev/null 2>&1 \ - || $echo 'page04.pst:' 'MD5 check failed' -5baa295de79c6c978bae3e496e32854e page04.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pst'`" - test 279 -eq "$shar_count" || - $echo 'page04.pst:' 'original size' '279,' 'current size' "$shar_count!" - fi -fi -rm -fr _sh00080 -exit 0 diff --git a/docs/tutorials/001/logger.h b/docs/tutorials/001/logger.h deleted file mode 100644 index 69d19505d60..00000000000 --- a/docs/tutorials/001/logger.h +++ /dev/null @@ -1,178 +0,0 @@ -// $Id$ - -#ifndef _CLIENT_HANDLER_H -#define _CLIENT_HANDLER_H - -/* A connection handler will also be derived from ACE_Event_Handler so - that we can register with a reactor. */ - -#include "ace/Event_Handler.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/INET_Addr.h" - -/* Since we're doing TCP/IP, we'll need a SOCK_Stream for the - connection. */ -#include "ace/SOCK_Stream.h" - -class Logging_Handler : public ACE_Event_Handler -{ -public: - /* - Like the acceptor, we're simple enough to avoid constructor and destructor. - */ - - /* To open the client handler, we have to register ourselves with - the reactor. Notice that we don't have to "open" our - ACE_SOCK_Stream member variable. Why? Because the call to the - acceptor's accept() method took care of those details for us. */ - - int open (ACE_Reactor *reactor) - { - /* - Remember our reactor... - */ - reactor_ = reactor; - - /* In this case we're using the READ_MASK. Like the acceptor, - handle_input() will be called due to this mask but it's a nice - piece of bookkeeping to have separate masks for the separate - types of activity. */ - - if (reactor->register_handler (this, - ACE_Event_Handler::READ_MASK) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) can't register with reactor\n"), - -1); - return 0; - } - - /* If we're explicitly closed we'll close our "file handle". The - net result is to close the connection to the client and remove - ourselves from the reactor if we're registered */ - - int close (void) - { - return this->handle_close (ACE_INVALID_HANDLE, - ACE_Event_Handler::RWE_MASK); - } - - /* This is a bit of magic... When we call the accept() method of - the acceptor object, it wants to do work on an ACE_SOCK_Stream. - We have one of those as our connection to the client but it would - be gross to provide a method to access that object. It's much - cooler if the acceptor can just treat the Logging_Handler as an - ACE_SOCK_Stream. Providing this cast operator lets that happen - cleanly. */ - - operator ACE_SOCK_Stream &() - { - return this->cli_stream_; - } - -protected: - - /* Again, like the acceptor, we need to provide the connection - handle to the reactor. */ - - ACE_HANDLE get_handle (void) const - { - return this->cli_stream_.get_handle (); - } - - /* And here's the handle_input(). This is really the workhorse of - the application. */ - - virtual int handle_input (ACE_HANDLE) - { - /* - Create and initialize a small receive buffer. The extra byte is - there to allow us to have a null-terminated string when it's over. - */ - char buf[BUFSIZ + 1]; - - /* Invoke the recv() method of the ACE_SOCK_Stream to get some - data. It will return -1 if there is an error. Otherwise, it - will return the number of bytes read. Of course, if it read - zero bytes then the connection must be gone. How do I know - that? Because handle_input() would not be called by the reactor - if there wasn't *some* kind of activity and a closed connection - looks like a read request to the reactor. But when you read - from a closed connection you'll read zero bytes. - - Notice that in the error case or closed case we return -1. That - tells the reactor to call our handle_close() where we'll take - care of shutting down cleanly. - - Although we don't make use of them, there are additional - parameters you can use with the recv() call. One of these is an - ACE_Time_Value that allows you to limit the amount of time - blocking on the recv(). You would use that if you weren't sure - if data was available. Since we only get to handle_input() when - data is ready, that would be redundant. On the other hand, if - you use recv_n() to read *exactly* a number of bytes then - limiting the time you wait for those bytes might be good. The - other paramter that may come in handy is an integer - <i>flags</i>. This is passed directly to the underlying OS - recv() call. See the man page recv(2) and the header - sys/socket.h for the gory details. */ - - ssize_t retval; - switch (retval = this->cli_stream_.recv (buf, BUFSIZ)) - { - case -1: - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) %p bad read\n", - "client logger"), - -1); - case 0: - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) closing log daemon (fd = %d)\n", - this->get_handle ()), - -1); - default: - buf[retval] = '\0'; - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) from client: %s", - buf)); - } - - return 0; - } - - /* When handle_input() returns -1, we'll end up here. There are a - few housekeeping chores to handle. */ - - int handle_close (ACE_HANDLE, - ACE_Reactor_Mask _mask) - { - /* Remove ourselves from the reactor. We have to include the - DONT_CALL in the mask so that it won't call handle_close() on us - again! */ - reactor_->remove_handler (this, - _mask | ACE_Event_Handler::DONT_CALL); - - /* Close the socket that we're connected to the client with. */ - cli_stream_.close (); - - /* Since we know we were dynamically allocated by the acceptor, - now is a good time to get rid of ourselves. */ - delete this; - - return 0; - } - -protected: - - /* Our peer connection. */ - ACE_SOCK_Stream cli_stream_; - - /* Our reactor (and our acceptor's reactor). */ - ACE_Reactor *reactor_; -}; - -#endif /* _CLIENT_HANDLER_H */ - diff --git a/docs/tutorials/001/page01.html b/docs/tutorials/001/page01.html deleted file mode 100644 index 3155a0b9c18..00000000000 --- a/docs/tutorials/001/page01.html +++ /dev/null @@ -1,102 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> -<HTML> -<HEAD> - <TITLE>ACE Tutorial 001</TITLE> - <META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (Win95; I) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> -</HEAD> -<BODY text = "#000000" link="#000fff" vlink="#ff0f0f" bgcolor="#ffffff"> - - -<CENTER><P><B><FONT SIZE=+2>ACE Tutorial 001<BR> -A Beginners Guide to Using the ACE Toolkit</FONT></B></P></CENTER> - -<hr> -<P>The purpose of this tutorial is to show you how to create a very simple -server capable of handling multiple client connections. Unlike a "traditional" -server application, this one handles all requests in one process. Issues -of multi-processing and multi-threading will be handled in later tutorials.</P> - -<P> -<HR WIDTH="100%"></P> - -<P>What do you need to create a server?</P> - -<OL> -<LI>Something which accepts connections from clients</LI> - -<LI>Something which handles established connections</LI> - -<LI>A main program loop that handles it all</LI> -</OL> - -<P>The ACE Acceptor provides a solution for our first requirement. -This class is given a TCP/IP port number on which it will listen for -incoming connections. When a connection is attempted, the acceptor will -create a new object (the handler) to deal with the client connection while -the acceptor goes back to listening for other connections.</P> - -<P>The ACE EventHandler solves our second requirement. This doesn't -seem obvious now but as we progress through this tutorial it will become -more clear.</P> - -<P>Finally, a simple <I>main()</I> function will provide our program loop. -After any program initialization, it will enter an infinite loop which -waits for connection attempts to the Acceptor or data "events" -on the EventHandler.</P> - -<P> -<HR WIDTH="100%"></P> - -<P>Before we continue, I need to introduce one more ACE concept: the Reactor. -</P> - -<P>I don't want to go into great detail at this time on what the Reactor -is, what it does and how it does it but it is necessary for you to understand -the basic function of a reactor because it is going to be in the first -piece of code you see. The figure below depicts the interrelationships -between the Reactor, the Acceptor and the application handler.</P> -<P> <center> <img src="simple.gif" align=center> </center> - -<P>Briefly:<BR> -The reactor is an object which reacts when things happen to other objects. -These things are called <I>events</I>. The <I>other objects</I> are communications -objects which you have <I>registered</I> with the reactor. At the time -of registration, you also specify which events you are interested in. The -reactor is notified by the operating system when the events of interest -occur within the registered objects. The reactor then uses member functions -of the registered object to process the event. Notice that the reactor -doesn't care what happens because of the event. It is the object's responsibility -to process the event correctly. The reactor simply notifies the object -of the event.</P> - -<P>Why use the reactor?</P> - -<P>That will become clear as the tutorial progresses. For now, however, -a brief answer would be this: it allows multiple simultaneous client connections -to be processed efficiently by a single-threaded server. </P> - -<P>Servers have traditionally created a separate thread or process for -each client served. For large-volume services (such as telnet and ftp) -this is appropriate. However, for small-volume services the overhead of -process creation far outweighs the actual work being done. So... folks -begin using threads instead of processes to handle the clients. This is -good also but still, in some cases, the overhead is too much to bear. Instead, -why not have a single thread handle several clients and use a more intelligent -load-balancing methodology than one-thread-or-process-per-client? -<i>Caveat: Handling all requests in one thread of one process is really -only good when the requests can be handled almost instantaneously.</i> -</P> - -<P>This is where the reactor's power and flexibility come into play. The -developer can create a simple, single-threaded application that is later -modified to thread-per-client, process-per-client or thread-pool solution. -<P> -If all of this is gibberish and makes you think that ACE is way to hard to -learn, don't worry. We'll go into all the details and explain as we go. -I only went into all of this so that it can kick around in the back of your -mind until you need it later. -<P> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/001/page02.html b/docs/tutorials/001/page02.html deleted file mode 100644 index 560f092dd21..00000000000 --- a/docs/tutorials/001/page02.html +++ /dev/null @@ -1,172 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> -<HTML> -<HEAD> - <TITLE>ACE Tutorial 001</TITLE> - <META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (Win95; I) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> -</HEAD> -<BODY text = "#000000" link="#000fff" vlink="#ff0f0f" bgcolor="#ffffff"> - - -<CENTER><P><B><FONT SIZE=+2>ACE Tutorial 001<BR> -A Beginners Guide to Using the ACE Toolkit</FONT></B></P></CENTER> - -<hr> -<P>From here, we to move on to the main program loop. In a way, we're -starting at the final product when we do this, but it is a very simple -piece of code and a good place to start. - -<P>The <A HREF="server.cpp">main</A> -program is really quite simple. The real work is done in the ACE derived -classes. - -<P> -Kirthika Parameswaran offers this abstract of Tutorial 1: -<UL> -<P> -This is a simple logging server example. -The Reactor is used to handle more than one client request using a -single thread of execution instead of one thread per client. The Reactor -reactes to events and demultiplexes the events to the appropriate -Event_Handler registered with it, using the "callback" technique. The -reactor runs in an infinte event loop handling all the incoming events. -<P> -The Logging_Acceptor listens at a SERVER PORT address and passively -waits for requests to arrive. The Acceptor is also an Event_Handler and -is registered with the Reactor. This way it is simply yet another -Event_Handler for the Reactor and hence no special processing is needed -for it. -<P> -Once a connection request occurs, the Acceptor accepts it and -a connection is established. The reactor instance is passed to the -handler so that it can register with the Reactor. It does so with an -ACE_Event_Handler::ACCEPT_MASK. -<P> -The Logging_Client is another Event_Handler which actually handles the -client requests in its handle_input() method. It is also registered -with the Reactor with the ACE_Event_Handler::READ_MASK. -<P> -The Event_Handlers can be unregistered from the Reactor using -handle_close() methods -or explicitly calling the remove_handler() methods. -<P> -This server application builds and executes succesfully waiting for -client requests to arrive. -<P> -</UL> -FYI (from Doug): -<UL> -The ACCEPT_MASK is defined in the ACE_Event_Handler class. It's used -to inform the Reactor that you want to register an event handler to -"accept" a connection passively. Not surprisingly, the ACE_Acceptor -component uses this. -<P> -The READ_MASK is also defined in the ACE_Event_Handler class. It's -used to inform the Reactor that you want to register an event handler -to "read" data from an established connection. -</UL> -<hr> -<PRE> -<font color=red>// $Id$</font> - -<font color=red>/* Include the header file where our client acceptor is defined. */</font> -<font color=blue>#include</font> "<A HREF="../../../ace/Reactor.h">ace/Reactor.h</A>" - -<font color=red>/* For simplicity, we create our reactor in the global address space. - In later tutorials we will do something more clever and - appropriate. However, the purpose of this tutorial is to introduce a - connection acceptance and handling, not the full capabilities of a - reactor. */</font> -ACE_Reactor *g_reactor; - -<font color=red>/* Include the header where we define our acceptor object. An - acceptor is an abstraction that allows a server to "<font color=green>accept</font>" - connections from clients. */</font> -<font color=blue>#include</font> "<font color=green>acceptor.h</font>" - -<font color=red>/* A TCP/IP server can listen to only one port for connection - requests. Well-known services can always be found at the same - address. Lesser-known services are generally told where to listen by - a configuration file or command-line parameter. For this example, - we're satisfied with simply hard-coding a random but known value. */</font> -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int -main (int, char *[]) -{ - <font color=red>/* Create a Reactor instance. Again, a global pointer isn't exactly - the best way to handle this but for the simple example here, it - will be OK. We'll get cute with it later. Note how we use the - ACE_NEW_RETURN macro, which returns 1 if operator new fails. */</font> - ACE_NEW_RETURN (g_reactor, - ACE_Reactor, - 1); - - <font color=red>/* Like the Reactor, I'm skimming over the details of the ADDR - object. What it provides is an abstraction for addressing services - in the network. All we need to know at this point is that we are - creating an address object which specifies the TCP/IP port on - which the server will listen for new connection requests. */</font> - ACE_INET_Addr addr (PORT); - - Logging_Acceptor *peer_acceptor; - - <font color=red>/* We now create an acceptor object. No connections will yet be - established because the object isn't "<font color=green>open for business</font>" at this - time. Which brings us to the next line... */</font> - ACE_NEW_RETURN (peer_acceptor, - Logging_Acceptor, - 1); - - <font color=red>/* where the acceptor object is opened. You'll find that most ACE - objects have to be open()ed before they're of any use to you. On - this open() call, we're telling the acceptor where to listen for - connections via the 'addr' object. We're also telling it that we - want it to be registered with our 'g_reactor' instance. */</font> - if (peer_acceptor->open (addr, g_reactor) == -1 ) - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>Opening Acceptor\n</font>"), - -1); - - ACE_DEBUG ((LM_DEBUG, - "<font color=green>(%P|%t) starting up server logging daemon\n</font>")); - - <font color=red>/* The reactor's handle_events member function is responsible for - looking at all registered objects and invoking an appropriate - member function when anything of interest occurs. When an event is - processed, the handle_events function returns. In order to get all - events, we embed this in an infinite loop. - - Since we put ourselves into an infinite loop, you'll need to - CTRL-C to exit the program. */</font> - - for (;;) - g_reactor->handle_events (); - - return 0; -} - -</PRE> -<HR WIDTH="100%"> - -<P>As I said, the main program is really quite simple: -<UL> -<LI> -Create an address for the <I>port</I> we want to listen to</LI> - -<LI> -Create an acceptor which listens on that address</LI> - -<LI> -Register the acceptor with a reactor to respond to the connection requests</LI> - -<LI> -Enter an infinite loop to let the reactor handle the events</LI> -</UL> -On the next page, we will take a look at the acceptor and how it responds -to new connection requests. - -<P> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/001/page03.html b/docs/tutorials/001/page03.html deleted file mode 100644 index 00a8d4c7646..00000000000 --- a/docs/tutorials/001/page03.html +++ /dev/null @@ -1,195 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> -<HTML> -<HEAD> - <TITLE>ACE Tutorial 001</TITLE> - <META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (Win95; I) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> -</HEAD> -<BODY text = "#000000" link="#000fff" vlink="#ff0f0f" bgcolor="#ffffff"> - - -<CENTER><P><B><FONT SIZE=+2>ACE Tutorial 001<BR> -A Beginners Guide to Using the ACE Toolkit</FONT></B></P></CENTER> - -<hr> -<P>Now we begin to look at the <A HREF="acceptor.h">acceptor</A> object. - -<P> -Kirthika has this analogy: -<P> -<UL> -Consider an office: -<P> -Reactor: Receptionist -<P> -Event_Handlers: various Departments catering to specific needs. -<P> -SERVER_PORT: door -<P> -Acceptor: Doorkeeper -<P> -Thus when a needy person (client) enters the open door (port) -maintained by the doorkeeper (acceptor waiting for connection -request), the receptionist(reactor) directs the person towards the -appropriate section (event_handler) which would cater to his needs. -</UL> -<P> -<HR> -<PRE> -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>_CLIENT_ACCEPTOR_H</font> -<font color=blue>#define</font> <font color=purple>_CLIENT_ACCEPTOR_H</font> - -<font color=red>/* A SOCK_Acceptor knows how to accept socket connections. We'll use - one of those at the heart of our Logging_Acceptor. */</font> -<font color=blue>#include</font> "<A HREF="../../../ace/SOCK_Acceptor.h">ace/SOCK_Acceptor.h</A>" - -<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>) -<font color=blue># pragma</font> <font color=purple>once</font> -<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font> - -<font color=red>/* An Event_Handler is what you register with ACE_Reactor. When - events occur, the reactor will callback on the Event_Handler. More - on that in a few lines. */</font> -<font color=blue>#include</font> "<A HREF="../../../ace/Event_Handler.h">ace/Event_Handler.h</A>" - -<font color=red>/* When a client connects, we'll create a Logging_Handler to deal with - the connection. Here, we bring in that declaration. */</font> -<font color=blue>#include</font> "<font color=green>logger.h</font>" - -<font color=red>/* Our Logging_Acceptor is derived from ACE_Event_Handler. That lets - the reactor treat our acceptor just like every other handler. */</font> -class Logging_Acceptor : public ACE_Event_Handler -{ -public: - - <font color=red>/* For this simple case we won't bother with either constructor or - destructor. In a real application you would certainly have them. */</font> - - <font color=red>/* Here's the open() method we called from main(). We have two - things to accomplish here: (1) Open the acceptor so that we can - hear client requests and (2) register ourselves with the reactor - so that we can respond to those requests. */</font> - int open (const ACE_INET_Addr &addr, - ACE_Reactor *reactor) - { - <font color=red>/* Perform the open() on the acceptor. We pass through the - address at which main() wants us to listen. The second - parameter tells the acceptor it is OK to reuse the address. - This is necessary sometimes to get around closed connections - that haven't timed out. */</font> - if (this->peer_acceptor_.open (addr, 1) == -1) - return -1; - - <font color=red>/* Remember the reactor we're using. We'll need it later when we - create a client connection handler. */</font> - reactor_ = reactor; - - <font color=red>/* Now we can register with the reactor we were given. Since the - reactor pointer is global, we could have just used that but it's - gross enough already. Notice that we can pass 'this' right into - the registration since we're derived from ACE_Event_Handler. We - also provide ACCEPT_MASK to tell the reactor that we want to - know about accept requests from clients. */</font> - return reactor->register_handler (this, - <font color=#008888>ACE_Event_Handler::ACCEPT_MASK</font>); - } - -private: - - <font color=red>/* To provide multi-OS abstraction, ACE uses the concept of - "<font color=green>handles</font>" for connection endpoints. In Unix, this is a - traditional file descriptor (or integer). On other OS's, it may - be something else. The reactor will need to get the handle (file - descriptor) to satisfy it's own internal needs. Our relevant - handle is the handle of the acceptor object, so that's what we - provide. */</font> - ACE_HANDLE get_handle (void) const - { - return this->peer_acceptor_.get_handle (); - } - - <font color=red>/* When an accept request arrives, the reactor will invoke the - handle_input() callback. This is where we deal with the - connection request. */</font> - virtual int handle_input (ACE_HANDLE handle) - { - <font color=red>/* The handle provided to us by the reactor is the one that - triggered our up-call. In some advanced situations, you might - actually register a single handler for multiple connections. - The _handle parameter is a way to sort 'em out. Since we don't - use that here, we simply ignore the parameter with the - ACE_UNUSED_ARG() macro. */</font> - ACE_UNUSED_ARG (handle); - - Logging_Handler *svc_handler; - - <font color=red>/* In response to the connection request, we create a new - Logging_Handler. This new object will be used to interact with - the client until it disconnects. Note how we use the - ACE_NEW_RETURN macro, which returns -1 if operator new fails. */</font> - ACE_NEW_RETURN (svc_handler, - Logging_Handler, - -1); - - <font color=red>/* To complete the connection, we invoke the accept() method call - on the acceptor object and provide it with the connection - handler instance. This transfers "<font color=green>ownership</font>" of the connection - from the acceptor to the connection handler. */</font> - if (this->peer_acceptor_.accept (*svc_handler) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>%p</font>", - "<font color=green>accept failed</font>"), - -1); - - <font color=red>/* Again, most objects need to be open()ed before they are useful. - We'll give the handler our reactor pointer so that it can - register for events as well. If the open fails, we'll force a - close(). */</font> - if (svc_handler->open (reactor_) == -1) - svc_handler->close (); - - return 0; - } - -protected: - - <font color=red>/* Our acceptor object instance */</font> - ACE_SOCK_Acceptor peer_acceptor_; - - <font color=red>/* A place to remember our reactor pointer */</font> - ACE_Reactor *reactor_; -}; - -<font color=blue>#endif</font> <font color=red>/* _CLIENT_ACCEPTOR_H */</font> - -</PRE> -<HR WIDTH="100%"></PRE> -It is important to notice here that we have done very little application-specifc -code in developing this object. In fact, if we take out the progress information, -the only app-specific code is when we create the new <I>Logging_Handler</I> -object to give to the <I>accept</I> function. You may begin to wonder why -there isn't a C++ template that does all of this coding for you. Actually, -the ACE toolkit happens to have one handy: -<UL>typedef ACE_Acceptor <<I>YourHandlerClass</I>, ACE_SOCK_ACCEPTOR> -<I>YourAcceptorClass</I>;</UL> -We would have used it like this: -<UL>typedef ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR> Client_Acceptor;</UL> -This will create a piece of code similar to what I've shown above. The -primary difference is that the <I>handle_input </I>function created by -the template does NOT register the handler with the reactor. In the long-run, -that is good for us because we can then move that logic into the <I>open</I> -function of the <I>Logging_Handler</I> and use a completely-generic acceptor. - -<P>Now that we know how to accept a connection request, let's move on to -the next page where we learn how to handle the actual connection. Even -though we just learned about this cool template thing, we will continue -to use the "hand-written" acceptor developed above. As I mentioned, the -only difference will be in the <I>open</I> function of the connection handler -anyway. - -<P> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/001/page04.html b/docs/tutorials/001/page04.html deleted file mode 100644 index 58bc6d5848e..00000000000 --- a/docs/tutorials/001/page04.html +++ /dev/null @@ -1,211 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> -<HTML> -<HEAD> - <TITLE>ACE Tutorial 001</TITLE> - <META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (Win95; I) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> -</HEAD> -<BODY text = "#000000" link="#000fff" vlink="#ff0f0f" bgcolor="#ffffff"> - - -<CENTER><P><B><FONT SIZE=+2>ACE Tutorial 001<BR> -A Beginners Guide to Using the ACE Toolkit</FONT></B></P></CENTER> - -<hr> -<P>Now we begin to look at the <A HREF="logger.h">logger</A> -object. - -<P> -<HR> -<PRE> -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>_CLIENT_HANDLER_H</font> -<font color=blue>#define</font> <font color=purple>_CLIENT_HANDLER_H</font> - -<font color=red>/* A connection handler will also be derived from ACE_Event_Handler so - that we can register with a reactor. */</font> - -<font color=blue>#include</font> "<A HREF="../../../ace/Event_Handler.h">ace/Event_Handler.h</A>" - -<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>) -<font color=blue># pragma</font> <font color=purple>once</font> -<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font> - -<font color=blue>#include</font> "<A HREF="../../../ace/INET_Addr.h">ace/INET_Addr.h</A>" - -<font color=red>/* Since we're doing TCP/IP, we'll need a SOCK_Stream for the - connection. */</font> -<font color=blue>#include</font> "<A HREF="../../../ace/SOCK_Stream.h">ace/SOCK_Stream.h</A>" - -class Logging_Handler : public ACE_Event_Handler -{ -public: - <font color=red>/* - Like the acceptor, we're simple enough to avoid constructor and destructor. - */</font> - - <font color=red>/* To open the client handler, we have to register ourselves with - the reactor. Notice that we don't have to "<font color=green>open</font>" our - ACE_SOCK_Stream member variable. Why? Because the call to the - acceptor's accept() method took care of those details for us. */</font> - - int open (ACE_Reactor *reactor) - { - <font color=red>/* - Remember our reactor... - */</font> - reactor_ = reactor; - - <font color=red>/* In this case we're using the READ_MASK. Like the acceptor, - handle_input() will be called due to this mask but it's a nice - piece of bookkeeping to have separate masks for the separate - types of activity. */</font> - - if (reactor->register_handler (this, - <font color=#008888>ACE_Event_Handler::READ_MASK</font>) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>(%P|%t) can't register with reactor\n</font>"), - -1); - return 0; - } - - <font color=red>/* If we're explicitly closed we'll close our "<font color=green>file handle</font>". The - net result is to close the connection to the client and remove - ourselves from the reactor if we're registered */</font> - - int close (void) - { - return this->handle_close (ACE_INVALID_HANDLE, - <font color=#008888>ACE_Event_Handler::RWE_MASK</font>); - } - - <font color=red>/* This is a bit of magic... When we call the accept() method of - the acceptor object, it wants to do work on an ACE_SOCK_Stream. - We have one of those as our connection to the client but it would - be gross to provide a method to access that object. It's much - cooler if the acceptor can just treat the Logging_Handler as an - ACE_SOCK_Stream. Providing this cast operator lets that happen - cleanly. */</font> - - operator ACE_SOCK_Stream &() - { - return this->cli_stream_; - } - -protected: - - <font color=red>/* Again, like the acceptor, we need to provide the connection - handle to the reactor. */</font> - - ACE_HANDLE get_handle (void) const - { - return this->cli_stream_.get_handle (); - } - - <font color=red>/* And here's the handle_input(). This is really the workhorse of - the application. */</font> - - virtual int handle_input (ACE_HANDLE) - { - <font color=red>/* - Create and initialize a small receive buffer. The extra byte is - there to allow us to have a null-terminated string when it's over. - */</font> - char buf[BUFSIZ + 1]; - - <font color=red>/* Invoke the recv() method of the ACE_SOCK_Stream to get some - data. It will return -1 if there is an error. Otherwise, it - will return the number of bytes read. Of course, if it read - zero bytes then the connection must be gone. How do I know - that? Because handle_input() would not be called by the reactor - if there wasn't *some* kind of activity and a closed connection - looks like a read request to the reactor. But when you read - from a closed connection you'll read zero bytes. - - Notice that in the error case or closed case we return -1. That - tells the reactor to call our handle_close() where we'll take - care of shutting down cleanly. - - Although we don't make use of them, there are additional - parameters you can use with the recv() call. One of these is an - ACE_Time_Value that allows you to limit the amount of time - blocking on the recv(). You would use that if you weren't sure - if data was available. Since we only get to handle_input() when - data is ready, that would be redundant. On the other hand, if - you use recv_n() to read *exactly* a number of bytes then - limiting the time you wait for those bytes might be good. The - other paramter that may come in handy is an integer - <i>flags</i>. This is passed directly to the underlying OS - recv() call. See the man page recv(2) and the header - sys/socket.h for the gory details. */</font> - - ssize_t retval; - switch (retval = this->cli_stream_.recv (buf, BUFSIZ)) - { - case -1: - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>(%P|%t) %p bad read\n</font>", - "<font color=green>client logger</font>"), - -1); - case 0: - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>(%P|%t) closing log daemon (fd = %d)\n</font>", - this->get_handle ()), - -1); - default: - buf[retval] = '\0'; - ACE_DEBUG ((LM_DEBUG, - "<font color=green>(%P|%t) from client: %s</font>", - buf)); - } - - return 0; - } - - <font color=red>/* When handle_input() returns -1, we'll end up here. There are a - few housekeeping chores to handle. */</font> - - int handle_close (ACE_HANDLE, - ACE_Reactor_Mask _mask) - { - <font color=red>/* Remove ourselves from the reactor. We have to include the - DONT_CALL in the mask so that it won't call handle_close() on us - again! */</font> - reactor_->remove_handler (this, - _mask | <font color=#008888>ACE_Event_Handler::DONT_CALL</font>); - - <font color=red>/* Close the socket that we're connected to the client with. */</font> - cli_stream_.close (); - - <font color=red>/* Since we know we were dynamically allocated by the acceptor, - now is a good time to get rid of ourselves. */</font> - delete this; - - return 0; - } - -protected: - - <font color=red>/* Our peer connection. */</font> - ACE_SOCK_Stream cli_stream_; - - <font color=red>/* Our reactor (and our acceptor's reactor). */</font> - ACE_Reactor *reactor_; -}; - -<font color=blue>#endif</font> <font color=red>/* _CLIENT_HANDLER_H */</font> - -</PRE> -<HR WIDTH="100%"> - -<P> -The comments really should tell the story. The really -interesting stuff is in <i>handle_input()</i>. Everything -else is just housekeeping. -In the future, we'll learn about ACE_Svc_Handler<> -which will take care of most of the housekeeping for us. -<P> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER> diff --git a/docs/tutorials/001/page05.html b/docs/tutorials/001/page05.html deleted file mode 100644 index 8725e1f410f..00000000000 --- a/docs/tutorials/001/page05.html +++ /dev/null @@ -1,54 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> -<HTML> -<HEAD> - <TITLE>ACE Tutorial 001</TITLE> - <META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (Win95; I) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> -</HEAD> -<BODY text = "#000000" link="#000fff" vlink="#ff0f0f" bgcolor="#ffffff"> - - -<CENTER><P><B><FONT SIZE=+2>ACE Tutorial 001<BR> -A Beginners Guide to Using the ACE Toolkit</FONT></B></P></CENTER> - -<hr> -<P>This concludes the first tutorial on using ACE. We've learned how to -create a simple server without knowing very much about network programming. - -<P>The code used in this tutorial is for illustration purposes. That means -it may or may not work. Actually, it <I>does</I> work but the -astute reader will notice a number of places for potential memory leaks. -We'll work on cleaning those up in future tutorials but if you find one -feel free to send me a fix and I'll integrate it into the tutorial. - -<UL> -<LI> -<A HREF="00SetEnv">Environment -Settings</A></LI> - -<LI> -<A HREF="Makefile">Makefile</A></LI> - -<LI> -<A HREF="server.cpp">main -program</A></LI> - -<LI> -<A HREF="acceptor.h">acceptor -object</A></LI> - -<LI> -<A HREF="logger.h">connection -handler</A></LI> -</UL> - -<P> -To read more about the patterns used in this example (as well as -quite a few which aren't!), you should check out -<A HREF="http://www.cs.wustl.edu/~schmidt/patterns-ace.html">http://www.cs.wustl.edu/~schmidt/patterns-ace.html.</A> -In fact, it's probably safe to say that the concepts found there will keep -coming back to haunt you as these tutorials continue. -<P> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> diff --git a/docs/tutorials/001/server.cpp b/docs/tutorials/001/server.cpp deleted file mode 100644 index f7deb7a9075..00000000000 --- a/docs/tutorials/001/server.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// $Id$ - -/* Include the header file where our client acceptor is defined. */ -#include "ace/Reactor.h" - -/* For simplicity, we create our reactor in the global address space. - In later tutorials we will do something more clever and - appropriate. However, the purpose of this tutorial is to introduce a - connection acceptance and handling, not the full capabilities of a - reactor. */ -ACE_Reactor *g_reactor; - -/* Include the header where we define our acceptor object. An - acceptor is an abstraction that allows a server to "accept" - connections from clients. */ -#include "acceptor.h" - -/* A TCP/IP server can listen to only one port for connection - requests. Well-known services can always be found at the same - address. Lesser-known services are generally told where to listen by - a configuration file or command-line parameter. For this example, - we're satisfied with simply hard-coding a random but known value. */ -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -int -main (int, char *[]) -{ - /* Create a Reactor instance. Again, a global pointer isn't exactly - the best way to handle this but for the simple example here, it - will be OK. We'll get cute with it later. Note how we use the - ACE_NEW_RETURN macro, which returns 1 if operator new fails. */ - ACE_NEW_RETURN (g_reactor, - ACE_Reactor, - 1); - - /* Like the Reactor, I'm skimming over the details of the ADDR - object. What it provides is an abstraction for addressing services - in the network. All we need to know at this point is that we are - creating an address object which specifies the TCP/IP port on - which the server will listen for new connection requests. */ - ACE_INET_Addr addr (PORT); - - Logging_Acceptor *peer_acceptor; - - /* We now create an acceptor object. No connections will yet be - established because the object isn't "open for business" at this - time. Which brings us to the next line... */ - ACE_NEW_RETURN (peer_acceptor, - Logging_Acceptor, - 1); - - /* where the acceptor object is opened. You'll find that most ACE - objects have to be open()ed before they're of any use to you. On - this open() call, we're telling the acceptor where to listen for - connections via the 'addr' object. We're also telling it that we - want it to be registered with our 'g_reactor' instance. */ - if (peer_acceptor->open (addr, g_reactor) == -1 ) - ACE_ERROR_RETURN ((LM_ERROR, - "Opening Acceptor\n"), - -1); - - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) starting up server logging daemon\n")); - - /* The reactor's handle_events member function is responsible for - looking at all registered objects and invoking an appropriate - member function when anything of interest occurs. When an event is - processed, the handle_events function returns. In order to get all - events, we embed this in an infinite loop. - - Since we put ourselves into an infinite loop, you'll need to - CTRL-C to exit the program. */ - - for (;;) - g_reactor->handle_events (); - - return 0; -} - diff --git a/docs/tutorials/001/simple.fig b/docs/tutorials/001/simple.fig deleted file mode 100644 index afea1bddabe..00000000000 --- a/docs/tutorials/001/simple.fig +++ /dev/null @@ -1,57 +0,0 @@ -#FIG 3.2 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -6 7800 5925 11850 6900 -2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5 - 11850 6900 11850 5925 7800 5925 7800 6900 11850 6900 -4 0 0 0 0 0 12 0.0000 4 180 3360 7800 6150 Application_Handler (ACE_Event_Handler)\001 -4 0 0 0 0 0 12 0.0000 4 180 3825 7950 6450 handle_input() {read connection, process data ... }\001 -4 0 0 0 0 0 12 0.0000 4 180 1335 7950 6675 get_handle() {...}\001 --6 -2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5 - 5100 7200 5100 5925 1725 5925 1725 7200 5100 7200 -2 1 1 1 1 7 0 0 -1 4.000 0 0 -1 1 0 2 - 2 1 1.00 60.00 120.00 - 4950 6600 7725 6600 -2 1 0 1 4 7 0 0 -1 0.000 0 0 -1 0 1 2 - 2 1 1.00 60.00 120.00 - 3900 5925 5400 2250 -2 1 0 1 4 7 0 0 -1 0.000 0 0 -1 0 1 2 - 2 1 1.00 60.00 120.00 - 8400 5925 6600 2250 -2 1 0 1 12 7 0 0 -1 0.000 0 0 -1 1 0 2 - 2 1 1.00 60.00 120.00 - 4500 5925 6000 2250 -2 1 0 1 12 7 0 0 -1 0.000 0 0 -1 1 0 2 - 2 1 1.00 60.00 120.00 - 9000 5925 7200 2250 -2 1 2 2 24 7 0 0 -1 3.000 0 0 -1 0 1 2 - 0 0 1.00 60.00 120.00 - 3300 7200 3300 8325 -2 1 0 2 15 7 0 0 -1 0.000 0 0 -1 1 1 2 - 0 0 1.00 60.00 120.00 - 0 0 1.00 60.00 120.00 - 9600 6900 9600 8025 -2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5 - 7500 2250 7500 1425 5100 1425 5100 2250 7500 2250 -4 0 0 0 0 0 12 0.0000 4 180 3045 1800 6150 Client_Acceptor (ACE_Event_Handler)\001 -4 0 0 0 0 0 12 0.0000 4 180 2565 1950 6450 handle_input() {open data conn ...\001 -4 0 0 0 0 0 12 0.0000 4 180 1755 3150 6675 create Handler Obj ... }\001 -4 0 0 0 0 0 12 0.0000 4 180 1335 1950 6900 get_handle() {...}\001 -4 0 1 0 0 0 12 0.0000 4 180 1800 5550 6450 create new Handler Obj\001 -4 0 24 0 0 0 12 0.0000 4 180 1530 2550 7800 Connection Request\001 -4 0 15 0 0 0 12 0.0000 4 135 1275 9000 7500 Data Connection\001 -4 0 0 0 0 0 12 0.0000 4 135 600 5925 1725 Reactor\001 -4 0 0 0 0 0 12 0.0000 4 180 1935 5325 2025 event handler dispatching\001 -4 0 0 0 0 0 12 0.0000 4 180 585 8175 4875 register\001 -4 0 0 0 0 0 12 0.0000 4 180 585 4650 5025 register\001 -4 0 0 0 0 0 12 0.0000 4 180 1110 4200 3675 handle_input()\001 -4 0 0 0 0 0 12 0.0000 4 180 975 4200 3900 get_handle()\001 -4 0 0 0 0 0 12 0.0000 4 180 1110 6675 3675 handle_input()\001 -4 0 0 0 0 0 12 0.0000 4 180 975 6675 3900 get_handle()\001 diff --git a/docs/tutorials/001/simple.gif b/docs/tutorials/001/simple.gif Binary files differdeleted file mode 100644 index ef29d88a120..00000000000 --- a/docs/tutorials/001/simple.gif +++ /dev/null |