// ------------------------------- // // -------- Start of File -------- // // ------------------------------- // // ----------------------------------------------------------- // // C++ Source Code File Name: client.cpp // C++ Compiler Used: MSVC40, HP CPP 10.24, egcs-2.90.29 // Produced By: Doug Gaer // File Creation Date: 09/20/1999 // Date Last Modified: 06/21/2000 // Copyright (c) 2000 Douglas M. Gaer // ----------------------------------------------------------- // // ------------- Program Description and Details ------------- // // ----------------------------------------------------------- // /* The VBS C++ classes are copyright (c) 2000, by Douglas M. Gaer. All those who put this code or its derivatives in a commercial product MUST mention this copyright in their documentation for users of the products in which this code or its derivative classes are used. Otherwise, you have the freedom to redistribute verbatim copies of this source code, adapt it to your specific needs, or improve the code and release your improvements to the public provided that the modified files carry prominent notices stating that you changed the files and the date of any change. THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE, YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. This program is used to demonstrate how to stream variable blocks across a network connection. */ // ----------------------------------------------------------- // #include <iostream.h> #include <stdlib.h> #include <string.h> #include "vbstream.h" #include "part.h" void SkipToEol(istream &s) // Used to clear istream { char c; s.clear(); while(s.get(c) && c != '\n') { ; } } void InputName(const char *mesg, PartData &part) { cout << mesg; char buf[PART_NAME_LEN]; for(unsigned i = 0; i < PART_NAME_LEN; i++) buf[i] = 0; cin >> buf; strcpy(part.name, buf); } void DisplayPart(PartData &part, int full = 1) { cout << endl; cout << "Item's Name = " << part.name << endl; if(full) { cout << "Stock Number = " << part.id << endl; cout.setf(ios::showpoint | ios::fixed); cout.precision(2); cout << "Price = $" << part.price << endl; cout << endl; } } void PrgMenu() { cout << endl; cout << "(a, A) Add an object to the database" << endl; cout << "(c, C) Change an object in the database" << endl; cout << "(d, D) Delete an object in the database" << endl; cout << "(f, F) Find an object in the database" << endl; cout << "(h, H, ?) Help (prints this menu)" << endl; cout << "(k, K) Shutdown the server" << endl; cout << "(q, Q) Quit this program" << endl; cout << endl; } void DeleteObject(int port, char *host) { vbStream client; if(client.StreamClient(port, host) != 0) { cout << client.SocketExceptionMessage() << endl; client.Close(); return; } cout << "Deleting an object from the database" << endl; PartData part; SkipToEol(cin); InputName("Enter the name of the object to delete: ", part); vbBlockHeader vb; vb.Length = sizeof(PartData); if(client.DeleteBlock((char *)&part, vb) != 0) cout << client.SocketExceptionMessage() << endl; client.Close(); } void AddObject(int port, char *host) { vbStream client; if(client.StreamClient(port, host) != 0) { cout << client.SocketExceptionMessage() << endl; client.Close(); return; } PartData part; SkipToEol(cin); InputName("Enter the name of the new part: ", part); int id; double price; cout << "Enter the part's stock number: "; cin >> id; if(cin) { part.id = id; cout << "Enter the part's price: $"; cin >> price; } else { cout << "Invalid entry. Object not added!" << endl; return; } if(cin) { part.price = price; } else { cout << "Invalid entry. Object not added!" << endl; return; } SkipToEol(cin); cout << "Sending a request to add the object" << endl; vbBlockHeader vb; vb.Length = sizeof(PartData); if(client.AddBlock((char *)&part, vb) != 0) cout << client.SocketExceptionMessage() << endl; client.Close(); } void ChangeObject(int port, char *host) { vbStream client; if(client.StreamClient(port, host) != 0) { cout << client.SocketExceptionMessage() << endl; client.Close(); return; } cout << "Changing and object in the database" << endl; PartData part; SkipToEol(cin); InputName("Enter the name of the part to change: ", part); PartData new_part_info; InputName("Enter the part's new name: ", new_part_info); int id; double price; cout << "Enter the part's new stock number: "; cin >> id; if(cin) { new_part_info.id = id; cout << "Enter the part's new price: $"; cin >> price; } else { cout << "Invalid entry. Object not added!" << endl; return; } if(cin) { new_part_info.price = price; } else { cout << "Invalid entry. Object not added!" << endl; return; } SkipToEol(cin); vbBlockHeader request_header; request_header.Length = sizeof(PartData); vbBlockHeader block_header; block_header.Length = sizeof(PartData); if(client.ChangeBlock((char *)&part, (char *)&new_part_info, request_header, block_header) != 0) cout << client.SocketExceptionMessage() << endl; client.Close(); } void ShutDownServer(int port, char *host) { vbStream client; if(client.StreamClient(port, host) != 0) { cout << client.SocketExceptionMessage() << endl; client.Close(); return; } cout << "Shutting down the server..." << endl; if(client.TerminateConnection() != 0) cout << client.SocketExceptionMessage() << endl; client.Close(); } void FindObject(int port, char *host) { vbStream client; if(client.StreamClient(port, host) != 0) { cout << client.SocketExceptionMessage() << endl; client.Close(); return; } cout << "Searching the database" << endl; PartData part; SkipToEol(cin); InputName("Enter the name of the object to find: ", part); vbBlockHeader request_header; request_header.Length = sizeof(PartData); vbBlockHeader requested_block_header; request_header.Length = sizeof(PartData); PartData *p = (PartData *)client.RequestBlock((char *)&part, request_header, requested_block_header); if(!p) { cout << client.SocketExceptionMessage() << endl; client.Close(); return; } cout << "Server has answered request" << endl; if(p->name[0] == 0) { cout << "The part was not found in the database" << endl; } else { cout << "Found the requested part: " << endl; DisplayPart(*(p)); } client.Close(); } int main(int argc, char **argv) { if(argc < 3) { cerr << "Usage: " << argv[0] << " hostname port" << endl; return 1; } unsigned short port = (unsigned short) atoi(argv[2]); char *host = argv[1]; char key; PrgMenu(); int rv = 1; while(rv) { if (!cin) { // Input is in fail state SkipToEol(cin); // Go to end of line if (!cin) { // Can't fix cout << "Input stream is broken" << endl; return 0; } } cout << '>'; cin >> key; if (!cin) continue; // Fix at top of loop switch(key) { case '?' : PrgMenu(); break; case 'h' : case 'H' : PrgMenu(); break; case 'q' : case 'Q' : rv = 0; break; case 'a' : case 'A' : AddObject(port, host); break; case 'c' : case 'C' : ChangeObject(port, host); break; case 'd' : case 'D' : DeleteObject(port, host); break; case 'f' : case 'F' : FindObject(port, host); break; case 'k' : case 'K' : ShutDownServer(port, host); break; default: cout << "Unrecognized command" << endl; } } return 0; } // ----------------------------------------------------------- // // ------------------------------- // // --------- End of File --------- // // ------------------------------- //