#!/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 2000-03-19 15:00 EST by <jcej@chiroptera.tragus.org>. # Source directory was `/home/jcej/projects/ACE_wrappers/docs/tutorials/009'. # # Existing files will *not* be overwritten unless `-c' is specified. # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 520 -rw-rw-r-- hdr # 59 -rw-rw-r-- bodies # 2184 -rw-rw-r-- page01.pre # 188 -rw-rw-r-- page02.pre # 296 -rw-rw-r-- page03.pre # 301 -rw-rw-r-- page04.pre # 995 -rw-rw-r-- page05.pre # 81 -rw-rw-r-- page02.pst # 96 -rw-rw-r-- page03.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 _sh32524; 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 <TITLE>ACE Tutorial 009</TITLE> </HEAD> <BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> X <CENTER><B><FONT SIZE=+2>ACE Tutorial 009</FONT></B></CENTER> X <CENTER><B><FONT SIZE=+2>Sending and receiving datagrams again</FONT></B></CENTER> X X <P> <HR WIDTH="100%"> SHAR_EOF $shar_touch -am 03191459100 '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' 808b7f288617f5b0a55256542f242912 hdr SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'hdr'`" test 520 -eq "$shar_count" || $echo 'hdr:' 'original size' '520,' '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 directed_client.cpp broadcast_client.cpp SHAR_EOF $shar_touch -am 0121195199 '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' 707d1735ca25694e2b5fddc1f6e7e124 bodies SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'bodies'`" test 59 -eq "$shar_count" || $echo 'bodies:' 'original size' '59,' '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>In our previous tutorial, we created a datagram listener and a couple of clients that would send it datagrams. That server would respond to any datagram sent to the TCP/IP port at which the server was listening. What we really want to do, however, is to have the server only respond to clients that meet some criteria. X <P>Why is this important? X <P>Imagine you're writting a distributed system that will have many server applications. Each of those will probably listen at different (and well-known) TCP/IP addresses so that clients can find each server without confusion. However... In a large system you might have several <I>versions</I> of the same server running at the same time*. You probably don't want those servers running at different addresses since that breaks the well-known address requirement. X <P>By creating a datagram listener similar to the last tutorial, a client can send broadcast datagrams to locate all of the servers listening at the well-known address. By adding a thin protocol layer into the datagram contents, the servers can be selective about which clients they respond to. Thus, if each client sends its version signature in the broadcast, then the servers can choose to respond only to clients with matching versions. <P> Kirthika's Abstract: <UL> Here, the client uses datagrams for discovery of the server in the subnet and also sends a signature for authentification. The server decides on replying to the client depending on the signature. The only changes from the previous tutorial are in the addition of an extra signature matching portion on the server side and providing timeout values on the client side which allows the send() and recv() calls to return on a timeout if the target party fails to respond. <P> This feature of discrimnation depending on the client signature could be used for security reasons or version confirmation by the server. </UL> <P><FONT SIZE=-1>*Note: I'm making the assumption that your multiple server versions will be running on different hosts since you can only have one server listening at the well-known address on a given host.</FONT> X SHAR_EOF $shar_touch -am 03191459100 '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' fa884a9f35740c89bf25c5eed9ba1ebd page01.pre SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page01.pre'`" test 2184 -eq "$shar_count" || $echo 'page01.pre:' 'original size' '2184,' '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' && X <P>Let's take a look at our new <A HREF="server.cpp">server.cpp</A> where we add in just a bit of code to examine the datagram contents before responding. X <P> <HR WIDTH="100%"><TT></TT> SHAR_EOF $shar_touch -am 03191459100 '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' 76a728cf5d0f42ca9b7d7a6fa0637384 page02.pre SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pre'`" test 188 -eq "$shar_count" || $echo 'page02.pre:' 'original size' '188,' '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' && X <P>Our new <A HREF="directed_client.cpp">directed_client.cpp</A> is very much like our previous one. The primary difference is the addition of a timeout to the recv() call so that we can exit somewhat gracefully if the server doesn't like what we have to say. X <P> <HR WIDTH="100%"> SHAR_EOF $shar_touch -am 03191459100 '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' c89d6d6f4acee2953a95469a3fe6965f page03.pre SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pre'`" test 296 -eq "$shar_count" || $echo 'page03.pre:' 'original size' '296,' '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' && X <P>As you can see in <A HREF="broadcast_client.cpp">broadcast_client.cpp</A>, there isn't enough difference to even comment on! Look back to the Tutorial 8 version of this file. The only difference is the addition of the timeout variable passed to recv(). X <P> <HR WIDTH="100%"><TT></TT> SHAR_EOF $shar_touch -am 03191459100 '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' 8c92e7ef51e85491bc2d7991a5b62cbb page04.pre SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pre'`" test 301 -eq "$shar_count" || $echo 'page04.pre:' 'original size' '301,' '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' && In this tutorial we've expanded on Tutorial 8 to provide a more discriminating server application. The changes to the clients were trivial, amounting to not much more than the addition of a timeout when reading a server's potential response. The server change was a bit more since it had to compare the clients' query with it's own signature. X <P>In a "real" system, the signatures you swap would probably include version information. You could even use a major/minor scheme where an exact match isn't necessary. Another upgrade might be to have a set of signatures at one or both ends of the conversation. The level of service provided by the server would be determined by the signature pair match. X <P>Here's the final file list: <UL> <LI> <A HREF="Makefile">Makefile</A></LI> X <LI> <A HREF="server.cpp">server.cpp</A></LI> X <LI> <A HREF="directed_client.cpp">directed_client.cpp</A></LI> X <LI> <A HREF="broadcast_client.cpp">broadcast_client.cpp</A></LI> </UL> X SHAR_EOF $shar_touch -am 03191459100 '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' 835e97e1b6ac1747ef9508936a56a6cc page05.pre SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page05.pre'`" test 995 -eq "$shar_count" || $echo 'page05.pre:' 'original size' '995,' '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>Let's move on and see what changes the clients require... X SHAR_EOF $shar_touch -am 03191459100 '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' 76a64b9c5c1d1baa1425085b1649fb31 page02.pst SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page02.pst'`" test 81 -eq "$shar_count" || $echo 'page02.pst:' 'original size' '81,' '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%"> X <P>On the next page, we see that the directed_client gets similar upgrades. X SHAR_EOF $shar_touch -am 03191459100 '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' 11fda077df9a3ef7155f33e75cc9b6b6 page03.pst SHAR_EOF else shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page03.pst'`" test 96 -eq "$shar_count" || $echo 'page03.pst:' 'original size' '96,' 'current size' "$shar_count!" fi fi rm -fr _sh32524 exit 0