Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Cookbook

This page is an introduction to Ishtar net by example. It covers the most important classes.

Stream interface

A stream is an object to which you can read/write data. In Ishtar, streams provide members for endian-safe operations. Stream classes inherit from two interfaces: Ishtar::InputStream for streams that can be read from and Ishtar::OutputStream for streams that can be written to. This library provides two implementations of streams: Ishtar::FileInputStream / Ishtar::FileOutputStream for reading/writing to files and Ishtar::Socket for reading/writing to the network.

Streams are very easy to use, the following code will open a file for writing and write some data into it:

{
    // open file output for writing
    Ishtar::FileOutputStream file("output");
    
    // write two unsigned int on 32 bits, endian-safe, that will be loaded correctly on any platform
    file.writeUInt32(0);
    file.writeUInt32(0xFF00FF00);
    
} // end of scope, file is closed

TCP/IP Client

Ishtar provides an easy way to create network clients. Simply create a subclass of Ishtar::NetworkClient and implement the two virtual methods Ishtar::NetworkClient::incomingData and Ishtar::NetworkClient::connectionClosed. Then instanciate the class and call Ishtar::NetworkClient::run if you want it to wait for network data and react on them. Additionally, if you need to do other things in your program, you can periodically call the Ishtar::NetworkClient::step method which will handle pending network data.

The following code will create a simple HTTP client which will retrieve a file from a web server:

testclient.cpp:

#include <ishtar/network.h>
#include <iostream>
#include <cstdlib>

// Simple network client that dumps data from the network
class SimpleNetworkClient : public Ishtar::NetworkClient
{
public:
    // Constructor, just create Ishtar::NetworkClient
    SimpleNetworkClient(const std::string &host, Ishtar::UInt16 port, const std::string &filename) :
        Ishtar::NetworkClient(host, port)
    {
        // Send first line header
        std::string request("GET ");
        request += filename;
        request += " HTTP/1.1\r\n";
        socket->write(request.c_str(), request.length());
        
        // Send second line header
        request = "Host: ";
        request += host;
        request += "\r\n\r\n";
        socket->write(request.c_str(), request.length());
        
        socket->flush();
    }
    
    // Incoming data, print them
    virtual void incomingData (Ishtar::Socket *socket)
    {
        // read and print result, inefficient because we read only one byte at a time
        std::cout << socket->readUInt8();
    }
    
    // Remote host has closed, print its name
    virtual void connectionClosed (Ishtar::Socket *socket)
    {
        std::cout << "Host " << socket->getRemoteName() << " has closed connection." << std::endl;
    }
};

int main(int argc, char *argv[])
{
    // we want the hostname and port as argument
    if (argc != 4)
    {
        std::cerr << "Usage " << argv[0] << " hostname port filename" << std::endl;
        exit(1);
    }
    
    // Create an instance of TCP/IP client
    SimpleNetworkClient client(argv[1], atoi(argv[2]), argv[3]);
    
    // Run the client forever
    client.run();
}

You can then compile this program, assuming its name is testclient.cpp, using the following command:

g++-3.4 testclient.cpp -o testclient -lishtarnet

TCP/IP Server

Ishtar provides an easy way to create network servers. Simply create a subclass of Ishtar::NetworkServer and implement the three virtual methods Ishtar::NetworkServer::incomingData, Ishtar::NetworkServer::incomingConnection and Ishtar::NetworkServer::connectionClosed. Then instanciate the class and call Ishtar::NetworkServer::run if you want it to wait for network data and react on them. Additionally, if you need to do other things in your program, you can periodically call the Ishtar::NetworkServer::step method which will handle pending network data.

The following code will create a trivial HTTP server which will send any file to any clients connecting, so beware of security issues:

testserver.cpp:

#include <ishtar/network.h>
#include <iostream>
#include <fstream>
#include <cstdlib>

// Simple network client that dumps data from the network
class SimpleNetworkServer : public Ishtar::NetworkServer
{
protected:
    // Read a string terminated by '\n'
    void getString(std::string &s, Ishtar::Socket *socket)
    {
        Ishtar::UInt8 c;
        while ((c = socket->readUInt8()) != '\n')
            s += c;
    }
public:
    // Constructor, just create Ishtar::NetworkServer
    SimpleNetworkServer(Ishtar::UInt16 port) : Ishtar::NetworkServer(port) { }
    
    // Incoming data, print them
    virtual void incomingData (Ishtar::Socket *socket)
    {
        // Trivial HTTP header parser
        std::string request;
        getString(request, socket);
        if (request.substr(0, 3) == "GET")
        {
            // Get filename
            std::string::size_type n = request.find_first_of(' ', 4);
            std::string filename = request.substr(4, n - 4);
            
            // Open file
            std::ifstream file(filename.c_str(), std::ios::binary);
            
            // Get length of file
            file.seekg (0, std::ios::end);
            size_t length = file.tellg();
            file.seekg (0, std::ios::beg);
            
            // Read file and write to socket
            char *buffer = new char[length];
            file.read(buffer, length);
            file.close();
            socket->write(buffer, length);
            socket->flush();
            
            // Close socket
            socket->disconnect();
            delete[] buffer;
        }
        else
            std::cerr << "Unknown request " << request << std::endl;
    }
    
    // Incoming connection, print name of host
    virtual void incomingConnection (Ishtar::Socket *socket)
    {
        std::cout << "Host " << socket->getRemoteName() << " has closed connected." << std::endl;
    }
    
    // Remote host has closed, print its name
    virtual void connectionClosed (Ishtar::Socket *socket)
    {
        std::cout << "Host " << socket->getRemoteName() << " has closed connection." << std::endl;
    }
};

int main(int argc, char *argv[])
{
    // we want the hostname and port as argument
    if (argc != 2)
    {
        std::cerr << "Usage " << argv[0] << " port" << std::endl;
        exit(1);
    }
    
    // Create an instance of TCP/IP server
    SimpleNetworkServer server(atoi(argv[1]));
    
    // Run the server forever
    server.run();
}

You can then compile this program, assuming its name is testserver.cpp, using the following command:

g++-3.4 testserver.cpp -o testserver -lishtarnet

You can test it by launching it with a port of your choice (here 8080):

./testserver 8080

And then connecting to it with your web browser, for example:

firefox http://127.0.0.1:8080

testserver will print the web browser request. If you then press stop on the web browser, testserver will notice the closed connection.


Generated on Mon Oct 24 17:30:54 2005 for libishtarnet by  doxygen 1.4.2