We need a concrete example to show how we use our receptionists. In this section, we define a simple client-server protocol, the greeting protocol, for this purpose. The greeting protocol is simple enough to be easily understood, yet complex enough to serve as an adequate demonstration.
Here's how the greeting protocol works. The greeting server has a well known address where it can be reached. By tradition, this address is TCP port 3010 on the server's home machine. Rogue Wave's greeting server lives at net.roguewave.com:3010, port 3010 on the net library home machine. Our example greeting server always attempts to brighten a client's day by responding with whatever greeting the previous client gave. First, let's suppose that you call the greeting server and send it a cheery salutation like "Hey dude!" followed by a newline character. The previous client called from Australia, so the server responds to you with "G'day mate!" The next client, calling from Waterloo, Canada, supplies the greeting "How's it going, eh." The server, remembering what you said, tells the client "Hey dude!" The following comic shows life from the server's point of view.
Here's a net library client application that exercises the greeting protocol.
#include <rw/toolpro/inetaddr.h> #include <rw/toolpro/sockport.h> #include <rw/toolpro/portstrm.h> #include <rw/toolpro/neterr.h>
main() { try { RWWinSockInfo info; RWSockAddr addr; //1 RWCString salutation; ... // Initialize addr and salutation ... RWSocketPortal portal(addr); //2 portal.sendAtLeast( salutation+RWCString("\n") ); //3
RWCString incoming; RWPortalIStream strm(portal); //4 incoming.readLine(strm); //5 } catch (const RWxmsg& x) { //6 cerr << "Error: " << x.why() << endl; }
return 0; }
Here's how the client program works:
//1 | The client connects to the server at address addr and sends it the salutation salutation. The details of initializing these objects are not discussed in this tutorial. |
//2 | This line connects portal to the greeting server. |
//3 | Send our greeting. The sendAtLeast() call is guaranteed to send the whole string provided as its argument. If necessary, it sends multiple packets to ensure that the entire string gets sent. |
//4 | Build a C++ input stream to receive the server's response. Using an istream allows us to use the RWCString member function readline() on the next line. |
//5 | Read the single line containing the server's response. The actual application code would now likely do something with the response, for example print it. |
//6 | If any of the net library calls used above fail, they throw an exception. This could happen, for example, if the greeting server is not running or if the host machine cannot be reached, perhaps because one of your colleagues tripped over your network cable and disconnected it. Rather than require you to check each net library call for an error condition, exceptions are used so that you can catch all errors in one place. In our client program, any troubles in the network code cause the flow of control to go to the catch block defined on this line. When an error does occur we just print out the error message and let the program end. Any open communication channels are automatically closed by the net library object destructors. |
©Copyright 2000, Rogue Wave Software, Inc.
Contact Rogue Wave about documentation or support issues.