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

FebMarch 2006Apr
SMTWTFS
2627281234
567891011
12131415161718
19202122232425
2627282930311
2345678

Archives

Topics

Tuesday, March 28, 2006 #

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 @ 8:59 PM

I am Mark, the Great and Powerful1, revered and feared throughout the great blue nowhere.

I am Mark Gordon, 17 years old, and currently attending Churchill High School in Michigan.  I am part of the Math, Science, and Computers program that my school runs which makes everyday... uh...  interesting.  Whether it be hopscotch on the desks2 in the computers room, or dancing to moskau3 (projecting the movie on a wall of course), we try to have fun.

As far as programming goes, I started on VB6, then moved to C++ and Java.  I kindof know how to use VB.Net.  I love working with WinAPI and sockets and geometry.  Alot of the code I post will likely be on those subjects.  I also like to write algorithms, so I try to participate on TopCoder4 as often as I can. (which hasn't been often lately, but I plan on doing the one tommorow)

Most of the code you will see on my blog will either be in C++ or VB, or maybe even Java. (or in the case of Aaform, a whole lot of languages)

 

Side Notes5

1.  I prefer to go my “Mark, the Great and Powerful“ in order to avoid confussion with the other Mark (drydo)

2.  This was quite the incident, a certain individual was jumping around on the desks when he slammed his head into the metal projector mount hung from the ceiling.  Before getting a paper towel to cover his head, he managed to bleed quite a bit.  I believe the story was that he accidentily fell and hit his head on the corner of a desk.

3.  This resulted in some detensions when the teacher walked in.

4.  You can check out my profile here

5.  I like side notes

posted @ 7:32 PM