#ifndef SOCKS_H #define SOCKS_H ///////////////////////////////////////////////////////////////////// // socks.h - socket client and multi-threaded server // // prototype for project #2 // // ver 1.9 // // Language: Visual C++, ver 6.0, SP 5 // // Platform: Dell Dimension 8100, Win 2000 Pro, SP 2 // // Application: CSE691/791 - SWM&A Demonstration // // Author: Jim Fawcett, CST 2-187, Syracuse Univ // // (315) 443-3948, jfawcett@twcny.rr.com // ///////////////////////////////////////////////////////////////////// /* Module Operations: ================== This module provides sockClt and sockSvr classes that create and use socket connections, using TCP/IP. To make connection you must create and start a server before attempting to connect a client. Public Interface - sockSvr: ============================ sockSvr server; // create socket server object server.start(); // start listing for incoming // connection requests Public Interface - sockClt: ============================ sockClt client; // create socket client object client.connectTo("127.0.0.1"); // connect to server at some IP client << "this is a message"; // send string to server */ // ///////////////////////////////////////////////////////////////////////// // Build Process for socks test stubs // ///////////////////////////////////////////////////////////////////////// // Required Files: // // socks.h, socks.cpp, connMgr.h, connMgr.cpp, msgHnd.h, msgHnd.cpp // // lockingPtr.h, lockingPtr.cpp, thrdsWithProc.h, thrdsWithProc.cpp,// // xmlTran.h, xmlTran.cpp, sysUtils.h, sysUtils.cpp // // // // Compiler: // // - create console projects sockServer and sockClient // // - add the files, listed above, to both projects, // // add the following settings to both projects // // - Project Settings\C/C++\category=code generation // // \Use run-time library\Debug Multithreaded // // - Project Settings\Link\Object/library modules: // // add wsock32.lib to end of list, preceded by a space // // // // Add the following setting to the sockServer project: // // - Project Settings\C/C++\category=general\Processor Definitions: // // add TEST_SOCKS_SERVER to end of list, preceded by a comma // // // // Add the following setting to the sockClient project: // // - Project Settings\C/C++\category=general\Processor Definitions: // // add TEST_SOCKS_CLIENT to end of list, preceded by a comma // // // // - Set Active Project to sockServer // // - compile, link, and run // // - Set Active Project to sockClient // // - compile, link, and run // // // // or, from command line: // // // // msdev sockServer.dsp /make /rebuild // // msdev sockClient.dsp /make /rebuild // // debug/sockServer // // debug/sockClient // // // ///////////////////////////////////////////////////////////////////////// // /* Maintenance History =================== ver 1.9 : 21 Nov 2001 - cosmetic changes to test stubs ver 1.8 : 20 Nov 2001 - fixed a bug in server queue processing that held onto the last message or two sent by the client until either another message is sent or a quit message is sent, which returns all messages. The fix entailed adding a second thread for each new client, so that there are now a receiving thread and a separate sending thread for each client. ver 1.7 : 17 Nov 2001 - fixed a bug in lockingPtr (see that module's maint. hist.) which resulted in minor changes to sockSvr::threadProc(...) and server's test stub main. - made cosmetic changes to threadProc and eliminated a redundant purge of the shared recvQ. - This now is a nearly complete prototype for CSE784 final project. ver 1.6 : 16 Nov 2001 - changed server sendQ lock from GlobalMutex to Mutex object held by connection manager. This allows the server to lock a single sendQ instead of locking all of them simultaneously - fixed a bug in server that lost messages because it shut down the client on getting a quit message without first checking whether there were pending messages in the recvQ. - fixed a potential bug (never witnessed a problem due to this bug) by locking recvQ while sending both an clientID message and the client's content message. ver 1.5 : 12 Nov 2001 - Added connection manager with multiple send queues and a single receive queue, used on the server side. Added a thread on server to start listener. ver 1.4 : 11 Nov 2001 - Added attempt to guarantee recving a specific number of bytes by retrying. Works just like the guaranteed send function. - Added message handling. Now sends real message objects. - Now is almost complete solution to CSE691 - Software Modeling and Analysis, Project #2, F01. - Also will be used as basis for developing a prototype for CSE784 - Software Studio final project. ver 1.3 : 06 Nov 2001 - Added a receive thread in client to listen for server messages. This is the first working demonstration of the thread class. ver 1.2 : 04 Nov 2001 - added two-way communication between client and server to their test stub's code - added trace commands ver 1.1 : 24 Oct 2001 - added manual and maintenance pages ver 1.0 : 23 Oct 2001 - first release Planned Modifications ===================== Need to: - add interface wrapper for queuing on both client and server sides - add id to message format - add resynchronize capability to message extractor on server. Plan to take most of this capability, added to the test stubs, and move it into drivers, so that the socks test stubs can just illustrate simple connections. */ // #include #include /////////////////////////////////////////////////////////////// // report WinSock errors // /////////////////////////////////////////////////////////////// enum reportMethod { console, window, exception }; void reportError(reportMethod rm); /////////////////////////////////////////////////////////////// // socket client class declaration // /////////////////////////////////////////////////////////////// const int MAX_MSG_SIZE = 1024; class sockSvr { public: sockSvr(int port); virtual ~sockSvr(); void start(); static int send(SOCKET sock, const char *block); static int recv(SOCKET sock, std::string &s, int numBytes=MAX_MSG_SIZE); bool good(); void clear(); protected: SOCKET _listener; int _listeningPort; const char *_clientAddress; bool _good; static unsigned int __stdcall threadProc(void *pArgs); private: sockSvr(const sockSvr&); // will not implement sockSvr& operator=(const sockSvr&); // will not implement }; inline bool sockSvr::good() { return _good; } inline void sockSvr::clear() { _good = true; } // /////////////////////////////////////////////////////////////// // socket client class declaration // /////////////////////////////////////////////////////////////// typedef std::string address; class sockClt { public: sockClt(); virtual ~sockClt(); bool connectTo(address &addr, int port); bool connectTo(const char *s, int port); int send(const char *block); int recv(std::string &s, int numBytes=MAX_MSG_SIZE); sockClt& operator<<(std::string &s); sockClt& operator<<(const char *s); sockClt& operator>>(std::string &s); void shutDownRecv(); void shutDownSend(); void shutDown(); void close(); bool good(); void clear(); protected: SOCKET _client; int _port; bool _good; private: sockClt(const sockClt&); // will not implement sockClt& operator=(const sockClt&); // will not implement }; inline bool sockClt::good() { return _good; } inline void sockClt::clear() { _good = true; } #endif