#ifndef SOCKUTIL_H #define SOCKUTIL_H /////////////////////////////////////////////////////////////////////// // sockUtils.h - sockets helper functions // // ver 1.1 // // // // Language: Visual C++, ver 6.0 // // Platform: Dell XBS1000r, Windows 2000 Professional // // Application: Demonstration for CSE691 - SW Mod & Anal // // Author: Jim Fawcett, CST 2-187, Syracuse Univ // // (315) 443-3948, jfawcett@twcny.rr.com // /////////////////////////////////////////////////////////////////////// /* Module Operations ================= This module provides means to communicate between two local or remote processes using Windows sockets. Communications are connected streams using the TCP/IP protocol. Definition ========== Socket servers typically spawn a new thread for each incoming connection request. This set of utilities uses the _beginthreadex function from the Win32 API for that purpose. You will need to provide a thread processing function, passed to startServer(...), with the signature: typedef unsigned(_stdcall *fnPtr)(void*); See the test stub for an example. Public Interface ================ if(err == SOCKET_ERROR) throwString(const char *msg, const char *file, int line); startSockets(); stopSockets(); SOCKET sock = createSocket(); connectToServer(sock, IPaddress, port); startSocketServer(listener, port, threadProc); bytesSent = send(sock, textBlock, blockLen); bytesRecvd = recv(sock, TextBuffer, bufLen); */ // /////////////////////////////////////////////////////////////////////////// // IDE build process // /////////////////////////////////////////////////////////////////////////// // Required Files: // // sockUtils.h, sockUtils.cpp, wsock32.lib // // // // Building Server in IDE: // // - create a Win32 Console project named server // // - add source files cited above // // - Project\Settings\C/C++\Category: // // select General // // \Preprocessor Definitions: // // enter ,TEST_SERVER at end of text in box // // - Project\Settings\C/C++\Category: // // select Code Generation // // \Use Run-Time Library: // // select Debug Multithreaded // // - Project\Settings\Link\Object/Library Modules: // // enter wsock32.lib // // - compile, link, and run // // - you should see the server waiting for input // // // // Building Client in IDE: // // - create a Win32 Console project named client // // - add source files cited above // // - Project\Settings\C/C++\Category: // // select General // // \Preprocessor Definitions: // // enter ,TEST_CLIENT at end of text in box // // - Project\Settings\C/C++\Category: // // select Code Generation // // \Use Run-Time Library: // // select Debug Multithreaded // // - Project\Settings\Link\Object/Library Modules: // // enter wsock32.lib // // - compile, link, and run // // - you should see the client sending text // // - you should see the server receiving the same text // // // // Note: Server will continue to run, waiting for connections, until // // you manually terminate by closing its window or typing ^c // // // /////////////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////////////// // Command Line build process // /////////////////////////////////////////////////////////////////////////// // required files: // // sockUtils.h, sockUtils.cpp // // // // compiler command line: // // cl /MTd /GX /DTEST_SERVER /Feserver.exe sockUtils.cpp wsock32.lib // // cl /MTd /GX /DTEST_CLIENT /Feclient.exe sockUtils.cpp wsock32.lib // /////////////////////////////////////////////////////////////////////////// /* Maintenance History =================== ver 1.0 : 08 Nov 99 - first release ver 1.1 : 22 Apr 04 - Digant Mehta and Ashish Poddar reported bugs that, it turns out, had the same cause. The threadProc I supplied did not make a copy of the SOCKET handle returned by the accept function and passed to it as the fourth argument of _begingthreadex. But, it needs to do that since the SOCKET handle will be overwritten each time a new client connects. That doesn't stop the first client from continuing to send since all that was overwritten was the SOCKET handle, the underlying socket is still intact, but does cause a crash when the socket connection is terminated. Bug now fixed. See the threadProc in the teststub for details. - This solution was suggested by Ashish. I changed the client to send messages continuously so that it is now easy to test concurrent client activities. */ // /////////////////////////////////////////////////////////////// // declarations // /////////////////////////////////////////////////////////////// #include /////////////////////////////////////////////////////////////// // sysError class declaration class sysError { public: sysError() {} ~sysError() {} std::string getLastMsg(); private: std::string _msg; }; typedef unsigned(_stdcall *fnPtr)(void*); void throwString(const char *msg, const char *file, int line); void startSockets(); void stopSockets(); SOCKET createSocket(); void connectToServer(SOCKET &sock, const char *IPaddress, int port); void startSocketServer(SOCKET &listener, int port, fnPtr threadProc); int send(SOCKET &sock, const char *block, int blockLen); int recv(SOCKET &sock, char *block, int blockLen); #endif