Ikaros Sockets

Christian Balkenius

Introduction

IKAROS_Socket is a small library that makes it easy to work with sockets in Ikaros. This library is used internally by the WebUI to allows access from a web browser, but can also be used in other cases when a module needs to communicate with other processes or with other devices on the Internet. Although it is not necessary to know anything about sockets to use Ikaros, it may be interesting to see how little code is necessary to set up socket communication with Ikaros.

Like the rest of Ikaros, the socket library runs on multiple platforms including Windows, Linux and OS X.

A Minimal Web Server

The functions in IKAROS_Socket can easily be used to build a minimal web server. The code example below implements a complete web server.

#include "IKAROS.h"

int
main(int argc, char *argv[])
{
  ServerSocket socket(80);
	
  while(true)
    if(socket.GetRequest() && socket.TestArgument(0, "GET"))
    {
        socket.SendFile("/WebDirectory", socket.GetArgument(1));
        socket.Close();
    }

  return 0;
}

The above code first opens a socket on port 80 which is the port number typically used for HTTP. The program then enters an infinite loop where it collects GET requests and processes them by sending the file specified in argument 1 in the request.

The function GetRequest() polss the socket to see if there is a message waiting and if there is, the function TestArgument() is used to test that the first argument is "GET". In this case, a reply is sent using the function SendFile(). Here, the file sent is the file received as the second argument of the HTTP request and GetArgument() is used to get this name from the request. The first argument to SendFile() specifies the directory where the function will look for the file.

Note that even if a particular directory is supplied to the function, it is possible to acces any part of your file hierarchy by specifying clever filenames to GET. You have to make sure that the filename does not lead outside the directory you want if you care at all for security.

If you want to test this example, it may be better to use another port than 80, since port number below 1024 are reserved for root. It is common to use port 8000 or port 8080 instead for a web server that runs on a user account.

If we wanted instead to generate the contents, for example xml data, we could replace the above code with the folllowing:

#include "IKAROS.h"

int
main(int argc, char *argv[])
{
  ServerSocket socket(80);
	
  while(true)
    if(socket.GetRequest() && socket.TestArgument(0, "GET"))
    {
      if(socket.TestArgument(1, "/data.xml"))
      {
        socket.Send("HTTP/1.1 200 OK\n");
        socket.Send("Content-Type: text/xml\n");
        socket.Send("\n");
		socket.Send("<?xml version='1.0' ?>\n");
        socket.Send("<xml>\n");
        socket.Send("<abc>ABC</abc>\n");
        socket.Send("</xml>\n");
        socket.Close();
      }
    }
  return 0;
}

In this example we test the path sent with the GET request and if it is "/data.xml", we start to send xml data using individual calls to Send.

Getting Data From A Server

Sockets in Ikaros also makes it very easy to retrieve data from a server. The following example illustrates how a Socket object can be used to request data from a server. The string "GET" is the request send to the server with ip number 127.0.0.1 at port 9000 and the maximum size of the returned data is 1024 bytes.

Socket socket;			
char buffer[1024];
socket.Get("127.0.0.1", 9000, "GET", data, 1024);

It is also possible to send and retreive data manually. The follwing example is equivalient to the code above:

Socket socket;			
char buffer[1024];
socket.SendRequest("127.0.0.1", 9000, "GET");
socket.ReadData(data, 1024);
socket.Close()

References

Balkenius, C., Morén, J. and Johansson, B. (2007). System-Level Cognitive Modeling with Ikaros.

Hall, B. (2007). Beej's Guide to Network Programming.

blog comments powered by Disqus