CDXConnection - TCP/IP Connection and communication library Author : Jimb Esser Date : 1-28-1 Version 1.0 Official homepage: http://www.horningabout.com/cdx/cdxconnection.html Summary: CDXConnection allows a programmer to easily create client-server networked applications without having to deal with lower level calls to the WinSock API and network interfaces. This library is *not* set up for communicating with an TCP/IP host, since it does not just send raw data, it sends formatted data with headers to allow for easier use in programs. If you just want a class to raw TCP/IP connections, check out Ian Perez's WinSockWrapper. On that note, extreme thanks to Ian Perez (fett@willcomp.com) for writing a WinSock wrapper with an example that I adapted for use in this class. This class requires wsock32.lib linked in and C++ Code Generation set to Multithreaded (/MT command line option). Detailed steps for setting up a MS VC++ project to use this class: These were written for MS VC++ 6.0, and some of the names of fields may be different on older/newer versions, but this hould be enough to get you started. 1) Create a new project (of any kind: Console, Win32 App, CDX AppWizard, etc) 2) Copy the files CDXConnection.h and CDXConnection.cpp into your projects directory 3) Add the files to your project (Project | Add | Files...) 4) Configure project settings: Go into Project | Settings a) Under the C++ tab, select "Code Generation" from the category dropdown list. On that page, choose either Multithreaded or Debug Multithreaded for the run-time library, depending on whether you're working in debug or release mode (by default you'll be in debug mode in a new project, and you'll have to do this again for release mode when you want to build a release version of your app). b) Under the Link tab, category General, you need to add "wsock32.lib" to the list of Object/Library modules along side of all of the rest. 5) Include "CDXConnection.h" in your code and you're ready to go! Look at ChatText.cpp for an example of a chat client and server with error checking and all of that jazz. To try it out, run the executable once and start tell it to be a server. Then run the executable again (either on the same computer or on different computers) and connect to the server and you can send messages that will be echoed on both the server and the other clients. Description of interface (see CDXConnection.h and .cpp for more details): CDXConnection(); // Default constructor ~CDXConnection(); // Default destructor /********** * BASICS * (enough to make a chat program) **********/ // Host Specific: /* CreateHost - needs to be called to make this connection object a server. */ HRESULT CreateHost(); /* Listen - the second step in creating a server. After starting the server listening, it will accept connections indefinitely unless you call stopAcceptingConnections() or setMaxConnections() iPort - The port to accept connections on. The clients must also be using the same port to connect. */ HRESULT Listen(unsigned short iPort); /* getNumConnections - returns the current number of clients connected */ int getNumConnections(); // Client Specific: /* CreateClient - needs to be called to make this connection object a client. */ HRESULT CreateClient(); /* Connect - attempts to connect to a server at the given address and port. The server must already be initialized and listening. */ HRESULT Connect(char *addr, unsigned short iPort); /* StillConnected - returns whether or not we're still connected to the server */ bool StillConnected(); // Returns false if a connection is lost /* getNodeNum - retrieves the node number that the server assigned to the client when it connected. */ int getNodeNum(); // For both: /* isDataReady - returns true if there is data ready to be read in */ bool isDataReady(); /* getData - reads 1 packet of data. getData will fail if the packet size is larger than iMaxSize or if there is any type of network error, including the client sending the data dropping it's connection. iNodeNum - if we are calling this from the server, the node of the client that sent the data will be returned in this variable. If we are calling this from a client, this should be 0. data - this points to a buffer to store the incoming data iMaxSize - the size of the data buffer - the largest amount that can be allowed to be read in. iNumRead - the count of bytes read in will be return here. iTag (optional) - if you are tagging your data the tag will be returned here. Note: isDataReady() must return true for getData to succeed */ HRESULT getData(int &iNodeNum, char *data, int iMaxSize, int &iNumRead, unsigned char *iTag = NULL); /* sendData - sends 1 packet of data. sendData will fail if there is any type of network error, including the client dropping it's connection. iNodeNum - if we are calling this from a client, this should be NODE_SERVER (0). Clients cannot send to other clients, since this is not a peer-to-peer model. If we are calling this from the server, the node of the client that we want to send the data to, or NODE_ALL to send the packet to all of the connected clients. data - this points to the data to send iSize - the size of the data to be sent iTag (optional) - allows you to attach a tag to the data indicating what type of data you are sending. This makes it easy to discriminate between different types of messages that will be passed between the client and server. Note: isDataReady() must return true for getData to succeed */ HRESULT sendData(int iNodeNum, const char *data, int iSize, unsigned char iTag = TAG_RAW); /************************** * Advanced Functionality * **************************/ // Server: /* stopAcceptingConnections - tells the server not to accept any more connections. To start accepting connections again, a call to Listen must be made. */ void stopAcceptingConnections(); /* setMaxConnections - sets the maximum number of connections to accept before stopping listening. When this number is reached it will not accept any more connections unless Listen is called again *even* if some of the current connections drop out. */ void setMaxConnections(int iMaxConnections); /* m_bConnectionLost - this flag is set to true when a connection has dropped from the server. */ bool m_bConnectionLost; // Set to true when someone has dropped out ToDo yet: Better handling of dropped clients Add a blocking readData call that blocks until data comes in