The wondering mind of Mark, the Great and Powerful

Mark Gordon's Blog at vbCity

This blog hosted by:
http://blogs.vbcity.com      
  Home :: Syndication  :: Login

AprMay 2008Jun
SMTWTFS
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

Archives

Topics

All code highlighting was done by SourceFormatX

Class: zsocket : Header | Html
Author: Mark, the Great and Powerful
Date of Creation: 9/2/05
Last Update: 3/11/06
Library Dependencies: Ws2_32.lib

zsocket is a handy class that I created that handles tcp communication similarily to the WinSock control. I implemented “events” (error, statechange, connectionrequest, and dataarrival) by having the client code inherit the zsocket class and override these methods. (You don't have to override any of them) All of the classes functionality is run on one seperate thread (for all instances of zsocket) so even if the thread that created the socket is busy, it can still continue to function. One thing you have to watchout for however is the fact that all the events are called by the single thread that runs all of the sockets. So if you do something in that thread that takes an excessive amount of time, no other sockets (including the current socket) can continue to function and recieve messages. Note that syncconnect and flush will allow sockets to continue to function.

Below are the avaliable functions that a deriving class can override

virtual void error(int num, std::string description) {}
virtual void statechange(SocketState oldstate) {}
virtual void connectionrequest(int requestid) {}
virtual void dataarrival(int bytessent) {}

Here is a sample cleint program using zsocket. It just simply connects to google and requests its homepage.

#include <iostream>
#include "zsocket.hpp"
using namespace std;
class mysck: public zsocket
{
public:
    virtual void error(int num, std::string description)
    {
        cout << "Error #" << num << "\t" << description << endl;
    }
    virtual void statechange(SocketState oldstate)
    {
        if (oldstate != sckConnected && state() == sckConnected)
        {
            cout << "CONNECTED :D" << endl;
            //issue request
            sendstring("GET / HTTP/1.1\r\n\r\n");
        }
    }
    virtual void connectionrequest(int requestid)
    {
        //This is a client program so it should not be recieving any requests
    }
    virtual void dataarrival(int bytessent)
    {
        //To get a string containing the data sent, call getdata()
        cout << getdata() << endl;
    }
};
int main()
{
    //Let's try it out
    zsocket * sck = new mysck();
    sck->sckconnect("www.google.com", 80);
    system("pause");
    delete sck;
    return 0;
}

Here is an example server program using zsocket. This is just a basic http server. For purposes of keeping this code segment short, it has a memory leak due to mysck instances not being deleted. After running this, try going to http://127.0.0.1

#include <iostream>
#include "zsocket.hpp"
using namespace std;
class mysck: public zsocket
{
public:
    virtual void error(int num, std::string description)
    {
        cout << "Error #" << num << "\t" << description << endl;
    }
    virtual void dataarrival(int bytessent)
    {
        //Being a simple server, we'll just send back a hello world
        sendstring("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nHello World");
    }
};
class myserver: public zsocket
{
public:
    virtual void error(int num, std::string description)
    {
        cout << "Error #" << num << "\t" << description << endl;
    }
    virtual void statechange(SocketState oldstate)
    {
        if (oldstate != sckListening && state() == sckListening)
        {
            cout << "LISTENING :D" << endl;
        }
    }
    virtual void connectionrequest(int requestid)
    {
        //spawn a socket to take the connection
        zsocket * sck = new mysck();
        sck->sckaccept(requestid);
    }
    virtual void dataarrival(int bytessent)
    {
        //This is a server socket so it shouldn't recieve data
        //but it could if it later connected or accepted a connection request
    }
};
int main()
{
    //Let's try it out
    zsocket * svr = new myserver();
    svr->scklisten(80);
    system("pause");
    delete svr;
    return 0;
}
Constructor
    zsocket();  //Creates a basic socket object and initializes the zsocket thread if needed
Methods
    //Syncronous connect methods
    bool syncconnect(std::string zhost, int zport,int timeout);
    bool syncconnect(int timeout);
    bool syncconnect(std::string zhost, int zport);
    bool syncconnect();
    //Asyncronous connect methods
    void sckconnect(std::string zhost, int zport, int timeout);
    void sckconnect(int timeout);
    void sckconnect(std::string zhost, int zport);
    void sckconnect();
    //Send methods
    void senddata(void * buf, int length);
    void sendstring(std::string str);
    void sendfile(std::string file);
    //Finishes sending all data for this socket
    void flush();
    //Recieve methods
    std::string getdata();  //Gets data and removes it from the buffer
    std::string peekdata();  //Gets data but does no remove it from the buffer
    //Listen functions
    bool scklisten(int zport);
    bool scklisten();
    //Other functions
    void close();  //Destroys the underlying socket object and creates a new one
    void sckaccept(int requestid);  //Accepts a connection request
    bool waitforconnection(int timeout);  //Attempts to wait for a connection request and connects to it
Properties
    //Local properties
    std::string localip();
    std::string localhost();
    //Remote properties
    std::string remoteip();
    std::string remotehost();
    int port(); //Port to listen on or connect to
    SocketState state(); //Current state of the socket
    int getlasttime(); //The last time (as returned by GetTickCount()) that the socket was sending or recieving data
    int timeout(); //Max timeout while attempting to connect
    int maxsendbuffersize(); //the maximum amount of data in bytes that can be sent in one packet.
    void sethost(std::string zhost); //Set the remote host
    void setport(int zport); //Set the port to listen on or connect to
    void settimeout(int ztimeout); //Set the time in milliseconds to attempt to connect
posted on Tuesday, March 28, 2006 8:59 PM