diff options
author | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-09-24 01:23:45 +0000 |
---|---|---|
committer | nobody <nobody@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1999-09-24 01:23:45 +0000 |
commit | 971b5fef4c0790745d71d7493090c54af9fc3b60 (patch) | |
tree | b9031b2eb4584c797d558a208156cb50296c257e /docs/tutorials/004 | |
parent | 39c67e8460275499ffcaf2ed95fe4df6cd157f28 (diff) | |
download | ATCD-pos_avsvc_split.tar.gz |
This commit was manufactured by cvs2svn to create tagpos_avsvc_split
'pos_avsvc_split'.
Diffstat (limited to 'docs/tutorials/004')
-rw-r--r-- | docs/tutorials/004/004.dsp | 100 | ||||
-rw-r--r-- | docs/tutorials/004/00SetEnv | 2 | ||||
-rw-r--r-- | docs/tutorials/004/Makefile | 47 | ||||
-rw-r--r-- | docs/tutorials/004/client.cpp | 215 | ||||
-rw-r--r-- | docs/tutorials/004/combine.shar | 216 | ||||
-rw-r--r-- | docs/tutorials/004/page01.html | 275 |
6 files changed, 0 insertions, 855 deletions
diff --git a/docs/tutorials/004/004.dsp b/docs/tutorials/004/004.dsp deleted file mode 100644 index 67106a5bf88..00000000000 --- a/docs/tutorials/004/004.dsp +++ /dev/null @@ -1,100 +0,0 @@ -# Microsoft Developer Studio Project File - Name="004" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Console Application" 0x0103
-
-CFG=004 - 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 "004.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 "004.mak" CFG="004 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "004 - Win32 Release" (based on "Win32 (x86) Console Application")
-!MESSAGE "004 - 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)" == "004 - 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)" == "004 - 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:"client.exe" /pdbtype:sept /libpath:"..\..\..\ace"
-
-!ENDIF
-
-# Begin Target
-
-# Name "004 - Win32 Release"
-# Name "004 - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\client.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# 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/004/00SetEnv b/docs/tutorials/004/00SetEnv deleted file mode 100644 index eca78e10c85..00000000000 --- a/docs/tutorials/004/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/004/Makefile b/docs/tutorials/004/Makefile deleted file mode 100644 index 0bfc82e3bd5..00000000000 --- a/docs/tutorials/004/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -#---------------------------------------------------------------------------- -# $Id$ -# -# Makefile for client logging applications -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = client - -LSRC = $(addsuffix .cpp,$(BIN)) - -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 - - -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) hdr bodies *.pre *.pst - -UNSHAR : # - sh combine.shar - -CLEAN : realclean - $(RM) hdr bodies *.pre *.pst .depend - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- diff --git a/docs/tutorials/004/client.cpp b/docs/tutorials/004/client.cpp deleted file mode 100644 index 33bada96743..00000000000 --- a/docs/tutorials/004/client.cpp +++ /dev/null @@ -1,215 +0,0 @@ -// $Id$ - -/* We need the connector object & we also bring in a simple string - class. */ -#include "ace/SOCK_Connector.h" -#include "ace/SString.h" - -/* In this tutorial, we extend SOCK_Stream by adding a few wrappers - around the send_n() method. */ -class Client : public ACE_SOCK_Stream -{ -public: - // Basic constructor - Client (void); - - /* 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.) */ - Client (const char *server, - u_short port); - - /* 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 easier. */ - int open (const char *server, - u_short port); - - /* These are necessary if you're going to use the constructor that - invokes open(). */ - int initialized (void) { return initialized_; } - int error (void) { return error_; } - - /* This is where the coolness lies. Most C++ folks are familiar - with "cout << some-data." 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); - -protected: - u_char initialized_; - u_char error_; -}; - -/* The basic constructor just sets our flags to reasonable values. */ -Client::Client(void) -{ - initialized_ = 0; - error_ = 0; -} - -/* 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) -{ - initialized_ = 0; - error_ = 0; - this->open (server, port); -} - -/* 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) -{ - /* This is right out of Tutorial 3. The only thing we've added is - to set the initialized_ member variable on success. */ - - 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); - initialized_ = 1; - return 0; -} - -/* The first of our put operators sends a simple string object to the - peer. */ -Client & -Client::operator<< (ACE_SString &str) -{ - /* 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. */ - - if (initialized () && !error ()) - { - /* Get the actual data held in the string object */ - const char *cp = str.fast_rep (); - - /* 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. */ - if (this->send_n (cp, - ACE_OS::strlen (cp)) == -1) - error_ = 1; - } - else - /* Be sure that error_ is set if somebody tries to use us when - we're not initialized. */ - error_ = 1; - - /* We have to return a reference to ourselves to allow chaining of - put operations (eg -- "server << foo << bar"). 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. */ - return *this ; -} - -/* 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 method in terms -of this one. There's always more than one way to do things! */ - -Client & -Client::operator<< (char *str) -{ - ACE_SString newStr (str); - - *this << newStr; - - return *this ; - - /* 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! */ -} - -/* 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) -{ - /* Create a character buffer large enough for the largest number. - That's a tough call but BUFSIZ should be quite enough. */ - char buf[BUFSIZ]; - - /* Put the number into our buffer... */ - ACE_OS::sprintf (buf, - "(%d)\n", - n); - - /* And create the ACE_SString that we know how to put. */ - ACE_SString newStr (buf); - - /* Send it and... */ - *this << newStr; - - /* return ourselves as usual. */ - return *this; -} - -/* Now we pull it all together. Like Tutorial 3, we'll allow command - line options. */ -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; - - /* Use the basic constructor since the other isn't really very safe. */ - Client peer; - - /* Open the server connection. Notice how this is simpler than - Tutorial 3 since we only have to provide a host name and port - value. */ - if (peer.open (server_host, - server_port) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "open"), - -1); - - for (int i = 0; i < max_iterations; i++) - { - /* Tell the server which iteration we're on. No more mucking - aroudn with sprintf at this level! It's all hidden from us. */ - peer << "message = " << i+1; - - /* Everything OK? */ - if (peer.error ()) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "send"), - -1); - else - ACE_OS::sleep (1); - } - - if (peer.close () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "close"), - -1); - return 0; -} diff --git a/docs/tutorials/004/combine.shar b/docs/tutorials/004/combine.shar deleted file mode 100644 index ba958b2fa14..00000000000 --- a/docs/tutorials/004/combine.shar +++ /dev/null @@ -1,216 +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-09-21 22:49 EDT by <jcej@chiroptera.tragus.org>. -# Source directory was `/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 -# 961 -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 _sh04745; 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<<() method. 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 0124114799 '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' -b1fef664f58233e14943041ed2765830 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 and 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 0124114999 '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' -63a7bcf418c9dd35d92caa17a6a4af7b page01.pst -SHAR_EOF - else - shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pst'`" - test 961 -eq "$shar_count" || - $echo 'page01.pst:' 'original size' '961,' 'current size' "$shar_count!" - fi -fi -rm -fr _sh04745 -exit 0 diff --git a/docs/tutorials/004/page01.html b/docs/tutorials/004/page01.html deleted file mode 100644 index 28a5479c80c..00000000000 --- a/docs/tutorials/004/page01.html +++ /dev/null @@ -1,275 +0,0 @@ -<!-- $Id$ --> -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 004</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 004</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>A much more clever Client</FONT></B></CENTER> - - -<P> -<HR WIDTH="100%"> - -<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<<() method. 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%"> -<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> "<A HREF="../../../ace/SOCK_Connector.h">ace/SOCK_Connector.h</A>" -<font color=blue>#include</font> "<A HREF="../../../ace/SString.h">ace/SString.h</A>" - -<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: - <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 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> - int initialized (void) { return initialized_; } - int error (void) { return error_; } - - <font color=red>/* This is where the coolness lies. Most C++ folks are familiar - 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. */</font> - Client &operator<< (ACE_SString &str); - Client &operator<< (char *str); - Client &operator<< (int n); - -protected: - u_char initialized_; - u_char error_; -}; - -<font color=red>/* The basic constructor just sets our flags to reasonable values. */</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. */</font> -<font color=#008888>Client::Client</font> (const char *server, - u_short port) -{ - initialized_ = 0; - error_ = 0; - this->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. */</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, - "<font color=green>%p\n</font>", - "<font color=green>open</font>"), - -1); - initialized_ = 1; - return 0; -} - -<font color=red>/* The first of our put operators sends a simple string object to the - peer. */</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 ()) - { - <font color=red>/* Get the actual data held in the string object */</font> - const char *cp = str.fast_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, - <font color=#008888>ACE_OS::strlen</font> (cp)) == -1) - error_ = 1; - } - 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 -- "<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 method in terms -of this one. There's always more than one way to do things! */</font> - -Client & -<font color=#008888>Client::operator</font><< (char *str) -{ - ACE_SString newStr (str); - - *this << newStr; - - 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. */</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 BUFSIZ should be quite enough. */</font> - char buf[BUFSIZ]; - - <font color=red>/* Put the number into our buffer... */</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 ? <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 peer; - - <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 (peer.open (server_host, - server_port) == -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. */</font> - peer << "<font color=green>message = </font>" << i+1; - - <font color=red>/* Everything OK? */</font> - if (peer.error ()) - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>%p\n</font>", - "<font color=green>send</font>"), - -1); - else - <font color=#008888>ACE_OS::sleep</font> (1); - } - - if (peer.close () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "<font color=green>%p\n</font>", - "<font color=green>close</font>"), - -1); - return 0; -} -</PRE> -<HR WIDTH="100%"> - -<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 and 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! - -<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... - -<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>. - -<P> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] </CENTER> |