summaryrefslogtreecommitdiff
path: root/docs/tutorials/004/page01.html
blob: 00eab3dd08ad6188c349518dfa924d80cf59df32 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
<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.&nbsp; A cooler thing to do is to overload
the C++&nbsp;put operator (&lt;&lt;) to put some data for us.&nbsp; That's
what we're going to do this time.&nbsp; (This tutorial is actually where
ACE_IOStream was born.)

<P>
<HR WIDTH="100%">

<P>The code:
<UL>
<PRE>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #include "ace/SOCK_Connector.h"
2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #include "ace/SString.h"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
3.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; class Client : public ACE_SOCK_Stream
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public:
4.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Client(void);
5.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Client( const char * server, u_short port );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
6.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int open( const char * server, u_short port );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
7.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inline int initialized(void) { return mInitialized; }
8.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inline int error(void)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { return mError; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
9.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Client &amp; operator&lt;&lt;( ACE_SString &amp; str );
10.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Client &amp; operator&lt;&lt;( char * str );
11.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Client &amp; operator&lt;&lt;( int&nbsp; n );
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; protected:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private:
12.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned char mInitialized;
13.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned char mError;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
14.&nbsp;&nbsp;&nbsp;&nbsp; Client::Client(void)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
15.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mInitialized = 0;
16.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mError = 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
17.&nbsp;&nbsp;&nbsp;&nbsp; Client::Client( const char * server, u_short port )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
18.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mInitialized = 0;
19.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mError = 0;
20.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (void)open(server,port);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
21.&nbsp;&nbsp;&nbsp;&nbsp; int Client::open( const char * server, u_short port )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
22.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ACE_SOCK_Connector connector;
23.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ACE_INET_Addr addr (port, server);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
24.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (connector.connect (*this, addr) == -1)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
25.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
26.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mInitialized = 1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
27.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return(0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
28.&nbsp;&nbsp;&nbsp;&nbsp; Client &amp; Client::operator&lt;&lt;( ACE_SString &amp; str )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
29.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( initialized() &amp;&amp; ! error() )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
30.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char * cp = str.rep();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
31.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mError = 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
32.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( this->send_n(cp,strlen(cp)) == -1 )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
33.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mError = 1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
34.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
35.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mError = 1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
36.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return *this ;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
37.&nbsp;&nbsp;&nbsp;&nbsp; Client &amp; Client::operator&lt;&lt; ( char * str )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
38.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ACE_SString newStr(str);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
39.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *this &lt;&lt; newStr;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
40.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return *this ;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
41.&nbsp;&nbsp;&nbsp;&nbsp; Client &amp; Client::operator&lt;&lt; ( int n )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // ACE_SString newStr;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // newStr = n;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
42.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char buf[1024];
43.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sprintf(buf,"(%d)\n",n);
44.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ACE_SString newStr(buf);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
45.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *this &lt;&lt; newStr;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
46.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return *this;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
47.&nbsp;&nbsp;&nbsp;&nbsp; int main (int argc, char *argv[])
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
48.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const char *server_host = argc > 1 ? argv[1]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : ACE_DEFAULT_SERVER_HOST;
49.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u_short server_port&nbsp;&nbsp;&nbsp;&nbsp; = argc > 2 ? ACE_OS::atoi (argv[2]) : ACE_DEFAULT_SERVER_PORT;
50.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int max_iterations&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = argc > 3 ? ACE_OS::atoi (argv[3]) : 4;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
51.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Client server(server_host,server_port);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
52.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( ! server.initialized() )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
53.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "intialization"), -1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
54.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; max_iterations; i++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
55.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server &lt;&lt; "message = " &lt;&lt; i+1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
56.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( server.error() )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
57.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "send"), -1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
58.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
59.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ACE_OS::sleep (1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
60.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (server.close () == -1)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
61.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "close"), -1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
62.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</PRE>
</UL>

<HR WIDTH="100%">

<P>Now, the code description:
<BR>&nbsp;
<OL>
<LI>
Get the SOCK&nbsp;Connector header</LI>

<LI>
and pickup a simple string class while we're at it.</LI>

<LI>
Create a simple derivative of ACE_SOCK_Stream.&nbsp; This is where we'll
add our put methods for sending the data to our server.&nbsp; Another approach
would have been to simply have an ACE_SOCK_Stream as a member variable.</LI>

<LI>
Boring constructor.</LI>

<LI>
Construct and open()&nbsp;all at once.</LI>

<LI>
Open the connection to the server.</LI>

<LI>
Are we connected to the server?</LI>

<LI>
Have we had an error?</LI>

<LI>
Send a string object to the server</LI>

<LI>
Send a "C" string to the server</LI>

<LI>
Send an integer to the server</LI>

<LI>
Intialization flag</LI>

<LI>
Error flag</LI>

<LI>
The boring constructor</LI>

<LI>
sets the initialization flag</LI>

<LI>
and the error flag to "false".</LI>

<LI>
The more exciting constructor</LI>

<LI>
sets the initialization flag</LI>

<LI>
and the error flag to false.</LI>

<LI>
But then it invokes open()&nbsp;to get us to the server.</LI>

<LI>
The open() method will connect us across the wire.</LI>

<LI>
First we need an ACE_SOCK_Connector (since we like sockets)</LI>

<LI>
And then we need an address which we can connect to.&nbsp; I suppose I
should have made the args to open()&nbsp;match those of the ACE_INET_Addr
constructor...</LI>

<LI>
Attempt to connect ourselves to the server.&nbsp; Since we're a derivative
of ACE_SOCK_Connector, it's legal to pass <I>this</I> to the connect()
method.</LI>

<LI>
As usual, failure results in a message and a bad return code.&nbsp; Rememer
that <I>mInitialized</I> will still be set to false indicating that we're
not connected.&nbsp; We should proabably also set <I>mError</I> to true.</LI>

<LI>
All is well, mark our selves as ready to go!</LI>

<LI>
Return our typical success value.&nbsp; (Unix folks will recognize this
as fairly standard behavior:&nbsp; 0 indicates success, anything else is
an error code.)</LI>

<LI>
Now we start to have some fun!&nbsp; Lets figure out how to "stream" a
string object.</LI>

<LI>
First we have to make sure that we're connected and in good health.</LI>

<LI>
Next, we get a character pointer to the string we want to send.</LI>

<LI>
No errors so far...</LI>

<LI>
Use our old friend <I>send_n()</I> to send the data at the pointer.&nbsp;
Use strlen() to figure out how many bytes to send.</LI>

<LI>
Oops!</LI>

<LI>
Ok, ok... if we're incapable of sending data</LI>

<LI>
then this must be an error.</LI>

<LI>
The put operator has to return a reference to itself so that we can string
them together:&nbsp; foobar &lt;&lt;&nbsp;this &lt;&lt;&nbsp;that</LI>

<LI>
Now, how about sending a character pointer?</LI>

<LI>
We're going to cheat and use the method we just wrote.&nbsp; The more sensible
thing would have been to write it in terms of <I>this</I> method.</LI>

<LI>
Send the string we just created.</LI>

<LI>
And again return ourselves.</LI>

<LI>
Sending the <I>char *</I> was easy since it's really just a block of contiguous
data.&nbsp; But how do we send an integer?&nbsp; Part of the point in using
the put operator is to convert the stuff to text instead of binary.</LI>

<LI>
So... create a temporary data buffer</LI>

<LI>
stuff our number into it</LI>

<LI>
and then create yet another string object.</LI>

<LI>
Now, we already know how to send those.</LI>

<LI>
And we're done!</LI>

<LI>
Finally, we get to the program entry point.</LI>

<LI>
Set the hostname we'll talk to</LI>

<LI>
and then choose the port</LI>

<LI>
and then decide how noisy to be.</LI>

<LI>
Use the do-it-all constructor to go ahead and setup our connection.</LI>

<LI>
Of course, it might have failed</LI>

<LI>
and we have to complain and exit.</LI>

<LI>
But if it worked, we start our <I>for</I> loop.</LI>

<LI>
See how easy &amp;&nbsp;intuitive it is to send stuff now?&nbsp; Just like
using <I>cerr</I> and <I>cout</I>!</LI>

<LI>
Make sure everything is OK.</LI>

<LI>
Sometimes it isn't.</LI>

<LI>
But...</LI>

<LI>
sometimes we can take a nap.</LI>

<LI>
Shut it all down.</LI>

<LI>
I&nbsp;guess it can fail too.</LI>

<LI>
But now we're done.</LI>
</OL>

<HR WIDTH="100%">

<P>Ok, now we're done with that.&nbsp; As you can see, it really isn't
so hard to create an object that makes sending data much more "natural"&nbsp;than
the typical send() invocation.&nbsp; You can even build up arbitrary objects
&amp; do some neat tricks with C++&nbsp;templates to stream their data
out as well.&nbsp; (We may go into that a little later.)&nbsp; Of course,
writting the full implementation such that these streams are interchangable
with the standard C++&nbsp;ostreams is quite a bit more difficult.

<P>As an exercise to the reader (don't you hate those!) I&nbsp;challenge
you to write the server side of this.&nbsp; You can take a&nbsp; 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>
<HR WIDTH="100%">
<CENTER></CENTER>

<CENTER>[<A HREF="../../tutorials">Tutorial Index</A>]</CENTER>

</BODY>
</HTML>