![]() |
Cliser Examples: TCP/IP (TCP) Echo Service over BSD Unix |
![]() |
Echo is a standard TCP/IP service used primarily for testing reachability, debugging software, and identifying routing problems. The service is defined for both the TCP and UDP communication protocols. In this example, we will build a client and server for the echo service in C++ using TCP.
An echo server listens for clients on port 7. When it receives a message from a client, an echo server simply transmits the message it received back to the client. A TCP (connection-oriented) echo server continuously echoes what the client sends it until the connection is closed.
A TCP daytime client thus connects to an echo server, reads what the user enters and sends it to the server, and then reads and displays the server's reply, until the user enters some kind of end-of-input sentinel (e.g., control-d, or the string quit).
To build a client and server for the daytime service, we follow the steps described previously:
$ java cliser.GUIThis will display the Cliser graphical user-interface, as shown below:
void Echo_TCP_BSD_Thread::interactWithClient() { string message; int numCharsReceived; for (;;) { numCharsReceived = this->receive(message); if (numCharsReceived == 0 || message == "") break; this->send(message); } }Our server customization is this simple because of the Cliser system architecture which, among other things, provides the easy-to-use, protocol-independent send() and receive() communication primitives.
Note that because the TCP protocol is connection-oriented, and the client connection is accepted prior to the execution of interactWithClient(), our method need only define what the server does to interact with the client.
The result is the file Echo_POSIX_Concurrent_TCP_BSD_Server.cpp.
void Echo_TCP_BSD_Client::interactWithServer() { string messageSent, messageReceived; const string SENTINEL = "quit"; cout << "Enter lines of text (" << SENTINEL << " to quit)\n"; for (;;) { getline(cin, messageSent); if ((messageSent == SENTINEL) || cin.eof()) break; this->send(messageSent); this->receive(messageReceived); cout << messageReceived << endl; } }The result is the file Echo_TCP_BSD_Client.cpp. As was the case with our server, our client customization is straightforward thanks to Cliser's simple send() and receive() communication primitives.
$ EchodIf you are not the system administrator, you can still run the server by giving a different port as a command-line argument:
$ Echod 7007This allows a server written for a standard service to be thoroughly tested before it is deployed. It also allows server-writers without sysadmin status to test their servers on unrestricted ports.
$ Echo ursa.calvin.eduor if your server is listening at port 7007 on myMachine.myDomain:
$ Echo myMachine.myDomain 7007A sample client session might be as follows:
tasting, tasting client tasting, tasting server strawberry client strawberry server lemon client lemon server orange client orange server quit