📄 combine.shar
字号:
chmod 0664 'page15.pre' ||
$echo 'restore of' 'page15.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 'page15.pre:' 'MD5 check failed'
adfd8e81c8c9eb43526d58322bbf8acf page15.pre
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page15.pre'`"
test 769 -eq "$shar_count" ||
$echo 'page15.pre:' 'original size' '769,' 'current size' "$shar_count!"
fi
fi
# ============= page16.pre ==============
if test -f 'page16.pre' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'page16.pre' '(file already exists)'
else
$echo 'x -' extracting 'page16.pre' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'page16.pre' &&
Recv is the sibling to Xmit. Again, they could be combined into a
single object if you want.
<P>
An ACE_Stream is designed to handle downstream traffic very
well. You put() data into it and it flows along towards the tail.
However, there doesn't seem to be a way to put data in such that it
will travel upstream. To get around that, I've added a get() method
to Recv that will trigger a read on the socket. Recv will then put
the data to the next upstream module and we're on our way. As noted
earlier, that data will eventually show up either in the <i>reader</i>
(if installed on the stream open()) or the stream head reader task's
message queue.
<HR>
SHAR_EOF
$shar_touch -am 04090120100 'page16.pre' &&
chmod 0664 'page16.pre' ||
$echo 'restore of' 'page16.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 'page16.pre:' 'MD5 check failed'
17e82c6427c779c22ac5c04c5f9c2bff page16.pre
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page16.pre'`"
test 659 -eq "$shar_count" ||
$echo 'page16.pre:' 'original size' '659,' 'current size' "$shar_count!"
fi
fi
# ============= page17.pre ==============
if test -f 'page17.pre' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'page17.pre' '(file already exists)'
else
$echo 'x -' extracting 'page17.pre' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'page17.pre' &&
The Recv implementation is nearly as simple as Xmit. There's
opportunity for error when we get the message size and we have to
manage the lifetime of the tickler but other than that it's pretty
basic stuff.
<HR>
SHAR_EOF
$shar_touch -am 04090120100 'page17.pre' &&
chmod 0664 'page17.pre' ||
$echo 'restore of' 'page17.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 'page17.pre:' 'MD5 check failed'
7db337f2c6ec74d75560534dec550b0e page17.pre
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page17.pre'`"
test 213 -eq "$shar_count" ||
$echo 'page17.pre:' 'original size' '213,' 'current size' "$shar_count!"
fi
fi
# ============= page18.pre ==============
if test -f 'page18.pre' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'page18.pre' '(file already exists)'
else
$echo 'x -' extracting 'page18.pre' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'page18.pre' &&
This and the next three pages present the protocol objects that
provide compression and encryption. If you were hoping to learn the
secrets of compression and encryption then I'm going to disappoint
you. There are some really good libraries out there that do this
stuff though and if anyone wants to integrate one of them into the
tutorial I'll be glad to take it!
<HR>
SHAR_EOF
$shar_touch -am 04090120100 'page18.pre' &&
chmod 0664 'page18.pre' ||
$echo 'restore of' 'page18.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 'page18.pre:' 'MD5 check failed'
dc5f706bd5a27009aed167c0b137648e page18.pre
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page18.pre'`"
test 372 -eq "$shar_count" ||
$echo 'page18.pre:' 'original size' '372,' 'current size' "$shar_count!"
fi
fi
# ============= page19.pre ==============
if test -f 'page19.pre' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'page19.pre' '(file already exists)'
else
$echo 'x -' extracting 'page19.pre' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'page19.pre' &&
Here we implement the details of our compression. By having both
compression and decompression in one object it's easier to keep track
of implementation details. Splitting Xmit/Recv like I did will make
things more difficult if something has to change in their interaction.
<HR>
SHAR_EOF
$shar_touch -am 04090120100 'page19.pre' &&
chmod 0664 'page19.pre' ||
$echo 'restore of' 'page19.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 'page19.pre:' 'MD5 check failed'
4eb5dcd181f180d6c460971903efb288 page19.pre
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page19.pre'`"
test 281 -eq "$shar_count" ||
$echo 'page19.pre:' 'original size' '281,' 'current size' "$shar_count!"
fi
fi
# ============= page20.pre ==============
if test -f 'page20.pre' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'page20.pre' '(file already exists)'
else
$echo 'x -' extracting 'page20.pre' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'page20.pre' &&
While I might be able to come up with a competitive compressor, I
don't have a snowball's chance to code up encryption. I'd be better
off piping the data through the standard Unix crypt command.
<P>
So, while I was lazy with Compress, I'm realistic with Crypt. I'll
show you the hooks and entry points and let someone else contribute an
encryptor.
<HR>
SHAR_EOF
$shar_touch -am 04090120100 'page20.pre' &&
chmod 0664 'page20.pre' ||
$echo 'restore of' 'page20.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 'page20.pre:' 'MD5 check failed'
2e697c01ac1579b409503b14980cadd0 page20.pre
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page20.pre'`"
test 355 -eq "$shar_count" ||
$echo 'page20.pre:' 'original size' '355,' 'current size' "$shar_count!"
fi
fi
# ============= page21.pre ==============
if test -f 'page21.pre' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'page21.pre' '(file already exists)'
else
$echo 'x -' extracting 'page21.pre' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'page21.pre' &&
The encryption implementation isn't any smarter than that of the
compressor. Still, the hooks are there for you to insert your
favorite library.
<HR>
SHAR_EOF
$shar_touch -am 04090120100 'page21.pre' &&
chmod 0664 'page21.pre' ||
$echo 'restore of' 'page21.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 'page21.pre:' 'MD5 check failed'
7f0f64452098cdef38c5496340a4b6c7 page21.pre
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page21.pre'`"
test 151 -eq "$shar_count" ||
$echo 'page21.pre:' 'original size' '151,' 'current size' "$shar_count!"
fi
fi
# ============= page22.pre ==============
if test -f 'page22.pre' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'page22.pre' '(file already exists)'
else
$echo 'x -' extracting 'page22.pre' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'page22.pre' &&
Well, this has certainly been one of the more verbose tutorials to
date. I must say "thanks" to everyone who stuck it out this far!
<P>
A quick review of what we've done:
<UL>
X
<LI>Create a simple client application and Client object that uses a
Protocol Stream without really knowing how they work. The app (and
object) rely on the public interface of the Protocol Stream to get the
job done. At this level the protocol details are irrelevant.
<P>
<LI>Next, we create a simple server application and Server object
similar to the client. The Protocol Stream is of course used and we
have to know a little more so that we can insert a <i>reader</i> that
will ultimately process the data from the client.
<P>
<LI>We then go into the details of the Protocol_Stream implementation
and it's Protocol_Task object that forms the basis for the stream
tasks. Each object is kept as small and simple as possible to improve
reusability and future maintenance.
<P>
<LI>Finally, the individual protocol objects are discused. Separate
objects for the peer interface were created as well as the bogus
compressor and encryptor. The protocol can be extended or modified by
creating new such objects and installing them in the Protocol_Stream's
open() method.
X
</UL>
<P>
X
It doesn't sound like much but it certainly took a bunch of files to
get there. It's easy to get lost in the details when there's so much
to cover so you're encouraged to go over things a couple of times.
As always, enhancments of the tutorials is welcome!
<P>
Here's the complete file list:
<UL>
<LI><A HREF="client">Makefile</A>
<P>
<LI><A HREF="Makefile.client">client Makefile</A>
<LI><A HREF="client.cpp">client.cpp</A>
<LI><A HREF="Client_i.h">Client_i.h</A>
<LI><A HREF="Client_i.cpp">Client_i.cpp</A>
<P>
<LI><A HREF="Makefile.server">Server Makefile</A>
<LI><A HREF="server.cpp">server.cpp</A>
<LI><A HREF="Server_i.h">Server_i.h</A>
<LI><A HREF="Server_i.cpp">Server_i.cpp</A>
<LI><A HREF="Handler.h">Handler.h</A>
<LI><A HREF="Handler.cpp">Handler.cpp</A>
<P>
<LI><A HREF="Protocol_Stream.cpp">Protocol_Stream.cpp</A>
<LI><A HREF="Protocol_Stream.h">Protocol_Stream.h</A>
<LI><A HREF="Protocol_Task.cpp">Protocol_Task.cpp</A>
<LI><A HREF="Protocol_Task.h">Protocol_Task.h</A>
<P>
<LI><A HREF="Xmit.cpp">Xmit.cpp</A>
<LI><A HREF="Xmit.h">Xmit.h</A>
<LI><A HREF="Recv.cpp">Recv.cpp</A>
<LI><A HREF="Recv.h">Recv.h</A>
<P>
<LI><A HREF="Compressor.cpp">Compressor.cpp</A>
<LI><A HREF="Compressor.h">Compressor.h</A>
<LI><A HREF="Crypt.cpp">Crypt.cpp</A>
<LI><A HREF="Crypt.h">Crypt.h</A>
</UL>
SHAR_EOF
$shar_touch -am 04090120100 'page22.pre' &&
chmod 0664 'page22.pre' ||
$echo 'restore of' 'page22.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 'page22.pre:' 'MD5 check failed'
da9603b9f082f453a905e40a8ca8523c page22.pre
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page22.pre'`"
test 2563 -eq "$shar_count" ||
$echo 'page22.pre:' 'original size' '2563,' '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>
<P>
Ok, that's it for the client. We've seen a very simple main()
X followed by an equally simple Client object.
<P>
For a quick look back:
<UL>
<LI><A HREF="Makefile.client">client Makefile</A>
<LI><A HREF="client.cpp">client.cpp</A>
<LI><A HREF="Client_i.h">Client_i.h</A>
<LI><A HREF="Client_i.cpp">Client_i.cpp</A>
</UL>
<P>
Now we'll move on and examine the server counter-part of our client.
SHAR_EOF
$shar_touch -am 04090120100 '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'
00419a8ab9a3ddae3261840b62afdc4a page04.pst
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page04.pst'`"
test 406 -eq "$shar_count" ||
$echo 'page04.pst:' 'original size' '406,' 'current size' "$shar_count!"
fi
fi
# ============= page09.pst ==============
if test -f 'page09.pst' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'page09.pst' '(file already exists)'
else
$echo 'x -' extracting 'page09.pst' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'page09.pst' &&
<HR>
<P>
That's it for the server-specific code. I think I've been fairly
successful in keeping it simple and to the point. There are a couple
of places where the as-yet-undescribed Protocol_Stream pops up and may
cause confusion. We're going to discuss that mystery now but before
we do here's the list of server files if you want to review:
X
<UL>
<LI><A HREF="Makefile.server">Server Makefile</A>
<LI><A HREF="server.cpp">server.cpp</A>
<LI><A HREF="Server_i.h">Server_i.h</A>
<LI><A HREF="Server_i.cpp">Server_i.cpp</A>
<LI><A HREF="Handler.h">Handler.h</A>
<LI><A HREF="Handler.cpp">Handler.cpp</A>
</UL>
<P>
SHAR_EOF
$shar_touch -am 04090120100 'page09.pst' &&
chmod 0664 'page09.pst' ||
$echo 'restore of' 'page09.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 'page09.pst:' 'MD5 check failed'
f88b5e21934f51fc3e14b154e5edd1a9 page09.pst
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'page09.pst'`"
test 616 -eq "$shar_count" ||
$echo 'page09.pst:' 'original size' '616,' 'current size' "$shar_count!"
fi
fi
rm -fr _sh16810
exit 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -