This library includes basic to advanced functionality for creating cross-platform client and server software. For anyone beginning to create network applications, I suggest starting with just the SockAPI and using the rest if you need them.
class MyThread : public Threadable { public: MyThread(myParms) { ... } // Your constructor virtual void main() { ... } // Your main };Construct/Call the thread:
EXAMPLE 1: void main() { Threadable::init(); MyThread *child = new MyThread(); child->spawn(); delete child; // WRONG!! Threadable deletes when appropriate! Threadable::done(); } EXAMPLE 2: void main() { Threadable::init(); MyThread child(); // WRONG!! Declare as a pointer or C++ will attempt // to delete the Threadable!! child.spawn(); Threadable::done(); }Rules governing threads
A basic understanding of networking would be very helpful here, but not necessary. Perhaps just knowing what you want to do will be enough. Minimal C++ knowledge is a must. For decent examples, both my WebDog and Netsuite programs make use of this library.
#include "Socket.h" // Socket library #define HTTP_PORT 80 // Port for web server void main() { Socket::init(); Socket sock; // Create a socket sock.connect("www.yahoo.com",HTTP_PORT); // Connect to Yahoo! /* If connection is successful, request index.html from their site. HTTP request is followed by a blank line to mark end of request. */ if (sock.isConnected()) { cout << sock.localName() << " connected to " << sock.peerName() << ":" << sock.peerPort() << endl; iostream client(&sock); // Connect socket to C++ IO stream client << "GET /index.html HTTP/1.0" << endl; client << endl; /* Now read Yahoo!'s response and display it on the screen. This will include both the HTTP result header and the HTML file. */ char buffer[512]; while (!client.eof() && sock.isConnected()) { client.read(buffer,sizeof(buffer)-1); cout.write(buffer,client.gcount()); } } Socket::done(); // Shutdown the socket library }
Next, we create a Socket named sock, which is an unconnected client socket. To connect to a site, we call socket.connect(char *hostname, int port). This connects to the specified server and port combination. The port tells the remote server what protocol we are using. Normally, web based services based on HTTP are on port 80. A list of these can be found at the Internet Assigned Numbers Authority or by asking someone who knows more than you.
Okay, now we make sure we are connected by calling sock.isConnected(). If we are, we now construct a typical C++ IO stream with the socket by creating an iostream named client with iostream client(streambuf *streamb). Now we can use standard C++ functions and operators such as read, write, << and >>, getline, etc. with the socket. If you are not familiar with these, learn them, they are the first C++ thing you should know.
Now we cheer by outputting a successful connection message. This will tell us our name, the remote name, and the port the remote is using to talk to us. Then we send the HTTP header. This is basically a GET with the filename we wish to get. This is part of HTTP and is not particularly important here.
Once the header is sent, the remote site will respond. We allocate a 512 byte buffer and display the response on screen. This is done with the client.read() and cout.write() calls. This is standard C++ style IO. Noteworthy is the while loop which checks for !client.eof() && sock.isConnected(). In this scenario, it is possible for the remote to abruptly disconnect(network error, modem hangup) so we must accomodate this possibility as well as eof().
When we are done, we simply call Socket::done. This will automatically shut down and close our socket. If we were to do another connection, we would call sock.close().
#include "SockAPI.h" #include <string.h> #define SERVER_PORT 5050 // Listen on this port void main() { Socket::init(); Socket serverSock(SERVER_PORT); // Create a socket for the server on this port Socket *clientSock; // Create a socket for the client char name[256]; serverSock.listen(); // Servers listen on sockets while (1) { // Our server runs forever// Wait for a connection iostream client(clientSock); // Create iostream to client /* Begin server processing here. We have a socket and an iostream. From here on this is basically console IO. */ client << "Enter your name now:" << endl; client >> name; if (strcmpi(name,"Moby Disk") == 0) client << "Welcome to my server!" << endl; else client << "Go away you bum!" << endl; delete clientSock; // Cleanup the client socket } Socket::done(); // In case we ever got here... }
This is structurally different from the client end, but few new Socket calls are required. We start by creating TWO sockets: one for the server, and one for the client currently engaged in conversation. serverSock is constructed differently from before by calling the constructor Socket(int port) This creates an unconnected server socket bound to the specified port. I choose port 5050 randomly.
Before the server enters its loop, we call serverSock.listen(). This tells the socket to listen on the specified port.
After we enter the loop, the server calls Socket *serverSock.accept(). The server is now blocked, waiting on a connection. Once a connect request is received, the function will return a pointer to a client Socket. The server must explicitly delete this pointer or the connection may remain open, and eat system resources.
The returned Socket is then used to create a C++ IO stream as before, and the server carries out is work. When the server is done, it deletes the client socket and loops. The IO stream is automatically deleted at each iteration of loop simply by declaring it inside the loop.