diff options
Diffstat (limited to 'docs/tutorials/004')
-rw-r--r-- | docs/tutorials/004/Makefile | 13 | ||||
-rw-r--r-- | docs/tutorials/004/combine.shar | 216 | ||||
-rw-r--r-- | docs/tutorials/004/page01.html | 188 |
3 files changed, 322 insertions, 95 deletions
diff --git a/docs/tutorials/004/Makefile b/docs/tutorials/004/Makefile index 06940b7f6c4..0ab1d500aa7 100644 --- a/docs/tutorials/004/Makefile +++ b/docs/tutorials/004/Makefile @@ -27,7 +27,18 @@ include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU include $(ACE_ROOT)/include/makeinclude/rules.local.GNU + +HTML : # + [ -f hdr ] || $(MAKE) UNSHAR + perl ../combine *.pre ; chmod +r *.html + +SHAR : # + [ ! -f combine.shar ] || exit 1 + shar -T hdr bodies *.pre *.pst > combine.shar && rm -f hdr bodies *.pre *.pst + +UNSHAR : # + sh combine.shar + #---------------------------------------------------------------------------- # Local targets #---------------------------------------------------------------------------- - diff --git a/docs/tutorials/004/combine.shar b/docs/tutorials/004/combine.shar new file mode 100644 index 00000000000..e77f85b0df4 --- /dev/null +++ b/docs/tutorials/004/combine.shar @@ -0,0 +1,216 @@ +#!/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:31 EST by <jcej@chiroptera.tragus.org>. +# Source directory was `/var/home/jcej/projects/ACE_wrappers/docs/tutorials/004'. +# +# Existing files will *not* be overwritten unless `-c' is specified. +# +# This shar contains: +# length mode name +# ------ ---------- ------------------------------------------ +# 591 -rw-rw-r-- hdr +# 18 -rw-rw-r-- bodies +# 702 -rw-rw-r-- page01.pre +# 963 -rw-rw-r-- page01.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 _sh00408; 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' && +<HTML> +<HEAD> +X <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> +X <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> +X <META NAME="Author" CONTENT="James CE Johnson"> +X <META NAME="Description" CONTENT="A first step towards using ACE productively"> +X <TITLE>ACE Tutorial 004</TITLE> +</HEAD> +<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> +X +<CENTER><B><FONT SIZE=+2>ACE Tutorial 004</FONT></B></CENTER> +X +<CENTER><B><FONT SIZE=+2>A much more clever Client</FONT></B></CENTER> +X +X +<P> +<HR WIDTH="100%"> +SHAR_EOF + $shar_touch -am 0117142999 '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' +f129543602285ef632d3ae560999a4db hdr +SHAR_EOF + else + shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" + test 591 -eq "$shar_count" || + $echo 'hdr:' 'original size' '591,' '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=1 +client.cpp +SHAR_EOF + $shar_touch -am 0117142999 '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' +d02fcd98e57e40350f82497be4ac0e0c bodies +SHAR_EOF + else + shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" + test 18 -eq "$shar_count" || + $echo 'bodies:' 'original size' '18,' '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' && +X +<P>Ok, so the last time around, we learned how to create a simple client +that can send a chunk of data. A cooler thing to do is to overload +the C++ put operator (<<) to put some data for us. That's what +we're going to do this time. (This tutorial is actually where ACE_IOStream +was born.) +<P> +Kirthika says: +<UL> +The cool thing about this "cooler" client is how we use a C++ trick for +streaming incoming data by using the operator<<() metod. Also the +Connector portion is wrapped in the open() method which now takes in the +server hostname and port. The result is a cleaner-looking client which +successfully interacts with the server, when connection is established. +</UL> +<HR WIDTH="100%"> +SHAR_EOF + $shar_touch -am 0117142999 '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' +74d3999cd710b35c8e6c26e558a926cb page01.pre +SHAR_EOF + else + shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" + test 702 -eq "$shar_count" || + $echo 'page01.pre:' 'original size' '702,' 'current size' "$shar_count!" + fi +fi +# ============= page01.pst ============== +if test -f 'page01.pst' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'page01.pst' '(file already exists)' +else + $echo 'x -' extracting 'page01.pst' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'page01.pst' && +<HR WIDTH="100%"> +X +<P>Ok, now we're done with that. As you can see, it really isn't +so hard to create an object that makes sending data much more "natural" +than the typical send() or send_n() invocation. You can even build +up arbitrary objects & do some neat tricks with C++ templates to stream +their data out as well. (We may go into that a little later.) +Of course, writting the full implementation such that these streams are +interchangable with the standard C++ ostreams is quite a bit more difficult. +In addition, there are a lot of optimizations that this client would benefit +from! +X +<P>As an exercise to the reader (don't you hate those!) I challenge you +to write the server side of this. You can take a look at IOStream_Test +in the ACE distribution if you get stuck... +X +<P>If you want to compile it yourself, here's the <A HREF="client.cpp">source</A>, +the <A HREF="Makefile">Makefile</A>, +and <A HREF="00SetEnv">Environment +settings</A>. +X +<P> +SHAR_EOF + $shar_touch -am 0117142999 'page01.pst' && + chmod 0664 'page01.pst' || + $echo 'restore of' 'page01.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 'page01.pst:' 'MD5 check failed' +c17e7bf6d06005bb1932f1790f8929fc page01.pst +SHAR_EOF + else + shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pst'`" + test 963 -eq "$shar_count" || + $echo 'page01.pst:' 'original size' '963,' 'current size' "$shar_count!" + fi +fi +rm -fr _sh00408 +exit 0 diff --git a/docs/tutorials/004/page01.html b/docs/tutorials/004/page01.html index d0e0adad6d4..1ed7799673e 100644 --- a/docs/tutorials/004/page01.html +++ b/docs/tutorials/004/page01.html @@ -31,54 +31,58 @@ server hostname and port. The result is a cleaner-looking client which successfully interacts with the server, when connection is established. </UL> <HR WIDTH="100%"> -<PRE>/* - We need the connector object & we also bring in a simple string class. - */ -#include "ace/SOCK_Connector.h" -#include "ace/SString.h" +<PRE> -/* +<font color=red>// $Id$</font> + +<font color=red>/* + We need the connector object & we also bring in a simple string class. + */</font> +<font color=blue>#include</font> "<font color=green>ace/SOCK_Connector.h</font>" +<font color=blue>#include</font> "<font color=green>ace/SString.h</font>" + +<font color=red>/* In this tutorial, we extend SOCK_Stream by adding a few wrappers around the send_n() method. - */ + */</font> class Client : public ACE_SOCK_Stream { public: - // Basic constructor + <font color=red>// Basic constructor</font> Client(void); - /* + <font color=red>/* Construct and open() in one call. This isn't generally a good idea because you don't have a clean way to inform the caller when open() fails. (Unless you use C++ exceptions.) - */ + */</font> Client( const char * server, u_short port ); - /* + <font color=red>/* Open the connection to the server. Notice that this mirrors the use of ACE_SOCK_Connector. By providing our own open(), - we can hide the connector from our caller & make it's interaction + we can hide the connector from our caller & make it's interaction easier. - */ + */</font> int open( const char * server, u_short port ); - /* + <font color=red>/* These are necessary if you're going to use the constructor that invokes open(). - */ + */</font> inline int initialized(void) { return initialized_; } inline int error(void) { return error_; } - /* + <font color=red>/* This is where the coolness lies. Most C++ folks are familiar - with "cout << some-data". It's a very handy and easy way to + with "<font color=green>cout << some-data</font>". It's a very handy and easy way to toss data around. By adding these method calls, we're able to do the same thing with a socket connection. - */ - Client & operator<<( ACE_SString & str ); - Client & operator<<( char * str ); - Client & operator<<( int n ); + */</font> + Client & operator<<( ACE_SString & str ); + Client & operator<<( char * str ); + Client & operator<<( int n ); protected: unsigned char initialized_; @@ -86,46 +90,46 @@ protected: }; -/* +<font color=red>/* The basic constructor just sets our flags to reasonable values. - */ -Client::Client(void) + */</font> +<font color=#008888>Client::Client</font>(void) { initialized_ = 0; error_ = 0; } -/* +<font color=red>/* This constructor also sets the flags but then calls open(). If the open() fails, the flags will be set appropriately. Use the two inline method calls initialized() and error() to check the object state after using this constructor. - */ -Client::Client( const char * server, u_short port ) + */</font> +<font color=#008888>Client::Client</font>( const char * server, u_short port ) { initialized_ = 0; error_ = 0; (void)open(server,port); } -/* +<font color=red>/* Open a connection to the server. This hides the use of ACE_SOCK_Connector from our caller. Since our caller probably doesn't care *how* we connect, this is a good thing. - */ -int Client::open( const char * server, u_short port ) + */</font> +int <font color=#008888>Client::open</font>( const char * server, u_short port ) { - /* + <font color=red>/* This is right out of Tutorial 3. The only thing we've added is to set the initialized_ member variable on success. - */ + */</font> ACE_SOCK_Connector connector; ACE_INET_Addr addr (port, server); if (connector.connect (*this, addr) == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>open</font>"), -1); } initialized_ = 1; @@ -133,31 +137,31 @@ int Client::open( const char * server, u_short port ) return(0); } -/* +<font color=red>/* The first of our put operators sends a simple string object to the peer. -*/ -Client & Client::operator<<( ACE_SString & str ) +*/</font> +Client & <font color=#008888>Client::operator</font><<( ACE_SString & str ) { - /* + <font color=red>/* We have to be able to allow: server << foo << bar << stuff; To accomplish that, every << operator must check that the object is in a valid state before doing work. - */ + */</font> - if( initialized() && ! error() ) + if( initialized() && ! error() ) { - /* + <font color=red>/* Get the actual data held in the string object - */ - char * cp = str.rep(); + */</font> + const char * cp = str.rep(); - /* + <font color=red>/* Send that data to the peer using send_n() as before. If we have a problem, we'll set error_ so that subsequent << operations won't try to use a broken stream. - */ + */</font> if( this->send_n(cp,strlen(cp)) == -1 ) { error_ = 1; @@ -165,29 +169,29 @@ Client & Client::operator<<( ACE_SString & str ) } else { - /* + <font color=red>/* Be sure that error_ is set if somebody tries to use us when we're not initialized. - */ + */</font> error_ = 1; } - /* + <font color=red>/* We have to return a reference to ourselves to allow chaining of - put operations (eg -- "server << foo << bar"). Without the reference, + put operations (eg -- "<font color=green>server << foo << bar</font>"). Without the reference, you would have to do each put operation as a statement. That's OK but doesn't have the same feel as standard C++ iostreams. - */ + */</font> return *this ; } -/* +<font color=red>/* How do you put a char*? We'll take an easy way out and construct an ACE_SString from the char* and then put that. It would have been more efficient to implement -this with the body of the operator<<(ACE_SString&) method and then express that +this with the body of the operator<<(ACE_SString&) method and then express that method in terms of this one. There's always more than one way to do things! - */ -Client & Client::operator<< ( char * str ) + */</font> +Client & <font color=#008888>Client::operator</font><< ( char * str ) { ACE_SString newStr(str); @@ -195,104 +199,104 @@ Client & Client::operator<< ( char * str ) return *this ; - /* + <font color=red>/* Notice that we could have been really clever and done: return *this << ACE_SString(str); That kind of thing just makes debugging a pain though! - */ + */</font> } -/* +<font color=red>/* ACE_SString and char* are both about the same thing. What do you do about different datatypes though? Do the same thing we did with char* and convert it to ACE_SString where we already have a << operator defined. - */ -Client & Client::operator<< ( int n ) + */</font> +Client & <font color=#008888>Client::operator</font><< ( int n ) { - /* + <font color=red>/* Create a character buffer large enough for the largest number. That's a tough call but 1024 should be quite enough. - */ + */</font> char buf[1024]; - /* + <font color=red>/* Put the number into our buffer... - */ - ACE_OS::sprintf(buf,"(%d)\n",n); + */</font> + <font color=#008888>ACE_OS::sprintf</font>(buf,"<font color=green>(%d)\n</font>",n); - /* + <font color=red>/* And create the ACE_SString that we know how to put. - */ + */</font> ACE_SString newStr(buf); - /* + <font color=red>/* Send it and... - */ + */</font> *this << newStr; - /* + <font color=red>/* return ourselves as usual. - */ + */</font> return *this; } -/* +<font color=red>/* Now we pull it all together. Like Tutorial 3, we'll allow command line options. - */ + */</font> int main (int argc, char *argv[]) { const char *server_host = argc > 1 ? argv[1] : ACE_DEFAULT_SERVER_HOST; - u_short server_port = argc > 2 ? ACE_OS::atoi (argv[2]) : ACE_DEFAULT_SERVER_PORT; - int max_iterations = argc > 3 ? ACE_OS::atoi (argv[3]) : 4; + u_short server_port = argc > 2 ? <font color=#008888>ACE_OS::atoi</font> (argv[2]) : ACE_DEFAULT_SERVER_PORT; + int max_iterations = argc > 3 ? <font color=#008888>ACE_OS::atoi</font> (argv[3]) : 4; - /* + <font color=red>/* Use the basic constructor since the other isn't really very safe. - */ + */</font> Client server; - /* + <font color=red>/* Open the server connection. Notice how this is simpler than Tutorial 3 since we only have to provide a host name and port value. - */ + */</font> if( server.open(server_host,server_port) == -1 ) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1); + ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>open</font>"), -1); } for (int i = 0; i < max_iterations; i++) { - /* + <font color=red>/* Tell the server which iteration we're on. No more mucking aroudn with sprintf at this level! It's all hidden from us. - */ - server << "message = " << i+1; + */</font> + server << "<font color=green>message = </font>" << i+1; - /* + <font color=red>/* Everything OK? - */ + */</font> if ( server.error() ) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1); + ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>send</font>"), -1); } else { - ACE_OS::sleep (1); + <font color=#008888>ACE_OS::sleep</font> (1); } } if (server.close () == -1) { - ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1); + ACE_ERROR_RETURN ((LM_ERROR, "<font color=green>%p\n</font>", "<font color=green>close</font>"), -1); } return 0; -}</PRE> - +} +</PRE> <HR WIDTH="100%"> <P>Ok, now we're done with that. As you can see, it really isn't @@ -315,9 +319,5 @@ and <A HREF="00SetEnv">Environment settings</A>. <P> -<HR WIDTH="100%"> -<CENTER>[<A HREF="..">Tutorial -Index</A>]</CENTER> - -</BODY> -</HTML> +<P><HR WIDTH="100%"> +<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> |