Almighty Bus Error

Blog about computer science, code snippets and tips.

GitHub repository with examples here.
Currently a Computer Engineering student at FCT/UNL.
October 14, 2009 at 11:42pm
Tags: Introduction  Java  RMI 

Comments (View)

Java: Remote Method Invocation

The Java RMI (Remote Method Invocation) is a way to create distributed services. It is composed of RMIRegistry which is a name registry which saves the resources available (servers) in a JVM (Java Virtual Machine). The registry is, however, accessible through different JVM’s when configured.

Since all the invocations are remote, most arguments are passed by value. The exception is when an object the implements an interface that extends Remote. A server is passed by reference, since its concept (RemoteObject) requires that the information must to be consistent between all the clients accessing it.

Considering that the server object would be passed by value like any other argument. This means that for the server to be consistent between all clients, it would need for each client to relay the local changes of each individual server to the central server, this creates alot of useless workload since its easier to just change the central server directly, it would save CPU cycles and network traffic on the client side used to calculate the changes and the central server load doesn’t change.

Interface

public interface IStuffServer extends Remote { public void doStuff() throws RemoteException; }

Class

public class StuffServer extends UnicodeRemoteObject implements IInfoReceiver { StuffServer() throws RemoteException { super(); } public void doStuff() { System.out.println("Stuff done."); } }

Every method of a class which extends Remote might throw a RemoteException (network connectivity).

Registering a resource

To create a registry there is a static method in the class LocateRegistry named createRegistry which receives an integer that specifies the port in which the registry will listen for requests. For the registry to be able to communicate with other JVM’s, it is needed to enable it by defining a policy.

policy.all

grant { permission java.security.AllPermission "", ""; }; Please bear in mind this might be insecure for critical applications.

Creating a “public” registry
System.getProperties().put("java.security.policy", "policy.all");

if (System.getSecurityManager() == null) {
    System.setSecurityManager(new RMISecurityManager());
}

try { // start rmiregistry
    LocateRegistry.createRegistry(1099);
} catch (RemoteException e) 
{   /* registry already created*/   }

InfoServerImpl server = new InfoServerImpl();
Naming.rebind("/StuffServer", server);
System.out.println("StuffServer bound in registry");

After creating the registry, the static class Naming is used to bind a name to the class using the method rebind, which in the example is “/StuffServer”. This name is only known by the registry in the current JVM.

A registry can be accessed by a simple netbios-like link, for example “//localhost/StuffServer”.

Obtaining Server Reference

To obtain the server object reference the static Naming class is used again, this time with the lookup method. IInfoServer server = null; try { server = (IInfoServer) Naming.lookup("//localhost/StuffServer"); } catch(RemoteException e) { System.out.println("Server not found"); }

After the server reference is obtained all the interaction to it is the same of a local object, except it might fail/be slower because of network connectivity issues. server.doStuff();

The previous will print “Stuff done.” at the server’s console.

That was it about Java’s RMI. For more information go here.

Thank you for reading!

May 30, 2009 at 6:05pm

Comments (View)

Multicast: An UDP strong point

Multicast is a way to distribute UDP messages to multiple hosts in an automated fashion. It works by making every host join a group which is composed of an IP address in the range [224.0.0.0 - 239.255.255.255] and a port. Every message sent to a group will be delivered to every host that has joined it. Since it can generate alot of traffic, multicast is only used at a LAN or intranet level.

In Java, to use Multicast there is an object named MulticastSocket. It has mostly the same usage as the DatagramSocket but has an joinGroup method and makes the process join a multicast group:

MulticastSocket mso = new MulticastSocket( 9001 );
mso.joinGroup( InetAddress.getByName("224.0.5.8") );

For more information about receiving and sending messages in UDP go here.

May 27, 2009 at 9:08pm
Tags: Introduction  Proxy  HTTP  Java 

Comments (View)

HTTP Proxy: Java Implementation

Continuing from “Concept Introduction” we will now see how a possible implementation is done. To start implementing a proxy we must first create a simple server application which accepts a connection from a client to be redirected.

Creating Server

We start by creating a ServerSocket (for more information go here).

doIt( new ServerSocket( serverPort ) );

Now we need to implement the method doIt() which simply uses a non-stopping cycle to take requests.

public static void doIt( ServerSocket server )
{
    for(;;)
    {
        try
        {
            Socket request = server.accept();
            new RequestHandler( request ).start();
        }
        catch( IOException e )
        {   e.printStackTrace(); continue;  }
    }
}

Creating a RequestHandler

The object RequestHandler is the one that actually does all the work for one request. Because of that we thread it (more information here) so that the proxy can handle multiple requests at once. The utility functions used here are located at the end of the post.

The code to convert the request to HTTP/1.0 is as follows:

InputStream srcIs = source.getInputStream();
String req = readLine(srcIs);
Scanner head = new Scanner(req);
String request = head.next();
String[] link = parseUrl(head.next());

if(link[0].compareTo("http") != 0)
    throw new IOException("Incompatible Protocol");

request += String.format(" %s HTTP/1.0\r\n", link[3]);
String[] currentProperty = parseHttpHeader( readLine(srcIs) );

while(currentProperty != null)
{
    if(isBanned(currentProperty))
    {
        currentProperty = parseHttpHeader( readLine(srcIs) );
        continue;
    }
    request += String.format("%s:%s\r\n", currentProperty[0],
                                                    currentProperty[1]);
    currentProperty = parseHttpHeader( readLine(srcIs) );
}
request += "\r\n"; // Add last CRLF

The function isBanned is the filter for properties from HTTP/1.1:

private boolean isBanned(String[] property)
{
    return property[0].compareTo("Connection") == 0 ||
        property[0].compareTo("Keep-Alive") == 0 ||
        property[0].compareTo("Proxy-Connection") == 0;
}

Now that the request is ready, the only thing needed to be done, is to send the request and then dump the whole response from the server to the client.

InetAddress host = InetAddress.getByName(link[1]);
Socket destination = new Socket(host, Integer.parseInt(link[2]) );
OutputStream destOs = destination.getOutputStream();
InputStream destIs = destination.getInputStream();

destOs.write(request.getBytes());
dumpStream(destIs, source.getOutputStream());

destination.close();
source.close();

Note: source is a socket that is passed in the RequestHandler constructor.

Utility Functions

  • The parseHttpHeader function parses the properties that a normal HTTP request has so we can easily remove the properties that are exclusive to HTTP1.1.
public static String[] parseHttpHeader( String header )
{
    String[] result = new String[2];
    int pos0 = header.indexOf( ':' );
    if( pos0 == -1 )
        return null;
    result[0] = header.substring( 0, pos0 ).trim();
    result[1] = header.substring( pos0 + 1 ).trim();
    return result;
}
  • The readLine function keeps reading from a InputStream until it reaches a “\r\n”.
public static String readLine( InputStream is ) throws IOException
{
    StringBuffer sb = new StringBuffer();
    int c;
    while( (c = is.read() ) >= 0 ) {
        if( c == '\r' ) continue;
        if( c == '\n' ) break ;
        sb.append( new Character( (char)c ) );
    }
    return sb.toString();
}
  • The parseUrl function parses a header, for example “http://almightybuserror.com:5000/stuff/here/” will be transformed to: [“http”, “almightybuserror.com”, “5000”, “/stuff/here/”].
public static String[] parseUrl(String url)
{
    String result[] = new String[4];
    int i = url.indexOf(':');
    result[0] = url.substring(0, i); // Protocol
    result[1] = url.substring(i+3);
    i = result[1].indexOf(':'); // Get possibly a port number

    int j = result[1].indexOf('/');
    // To parse the rest of the request
    result[2] = (i > 0 ? result[1].substring(i+1, j) : "80");
    result[3] = result[1].substring(j); // Request
    result[1] = (i > 0 ? result[1].substring(0, i) :
                                result[1].substring(0, j));
    //Concat so only the host remains
    return result;
}
  • The dumpStream function will also be used, you can find it here.

Thank you for reading. Comments are welcome!

Note: Credits for the functions readLine and parseHttpHeader go to ASC Department.

May 19, 2009 at 11:16am
Tags: Snippet  Java 

Comments (View)

Snippet.Java: Dump InputStream → OutputStream

This piece of code keeps reading 1024 bytes from the InputStream and writing to the OutStream until the read function returns an error value (-1) which means there is not anything else to read.

protected void dumpStream( InputStream in, OutputStream out )
throws IOException {
    byte[] arr = new byte[1024];
    int n;
    do {
        n = in.read( arr );
        out.write( arr, 0, n );
    } while (n != -1);
}
May 7, 2009 at 9:19pm
Tags: Threading  Java 

Comments (View)

Threading in Java

A thread is a lightweight process that will act as the child of the process that created it. If the parent process is interrupted the child will be inherited by the kernel process, however, most of the times when the parent dies and child loses its purpose. A thread will seemingly run at the same time as the other processes which raises concurrency issues but this won’t be discussed in this article.

Threading in a Java implementation can be made by two ways: extending the Thread object and implementing the Runnable interface.

To create a thread in either way it is needed to implement the run() method. Run will be the entry execution point when a thread is created.

Extending Thread object

public class DummyThreadable extends Thread { DummyThreadable() { ; } //dummy constructor. public void Run() { //do some threaded stuff. } }

To create a thread and run it use the start method like the following:

new DummyThreadable().start();

Implementing Runnable interface

public class DummyThreadable implements Runnable { DummyThreadable() { ; } //dummy constructor. public void Run() { //do some threaded stuff. } }

To create a thread using a class that implements Runnable use the following example:

DummyThreadable t = new DummyThreadable(); new Thread(t).start();

A very useful method for thread programing is the sleep method. It receives a time in milliseconds (and optionally nanoseconds). It makes a thread stop its execution flow for the defined time.

long ms = 9001; int ns = 901; Thread.sleep(ms, ns);

Thank you for reading!

April 12, 2009 at 9:10pm
Tags: Introduction  Java  TCP 

Comments (View)

The connection-oriented network protocol

The TCP (Transmission Control Protocol) and unlike UDP it does have a connection definition within the protocol based on Acknowledge-type packets.

In TCP every sent information packet needs to be acknowledged by the destination and if it is missing, the packet is resent until there is confirmation thus creating a “connection” between two peers. If a packet is corrupted a request is to the source for a replacement. Because there is a need to acknowledge all sent packets and error correction, TCP becomes bulkier and slower than UDP but extremely reliable.

In Java, to implement TCP communication the following objects from the java.net.* package are used: Socket and ServerSocket. Other needed objects, from the java.io.* package: InputStream and OutputStream.

As you can see in Java there is such a thing as a Server and Client. A ServerSocket can be looked at as a Socket generator. Its accept method accepts an incoming connection from a client creating and returning a Socket object.

How to use a Socket:

Socket aSocket = new Socket( server, port );

Reading from the socket: InputStream is = aSocket.getInputStream(); Scanner in = new Scanner( is ); ( ... )

For more information on how to use a Scanner please refer to here.

Writing to the socket: OuputStream os = aSocket.getOutputStream(); byte[] message = new String( "Hello World!" ).getBytes(); os.write( message );

Closing a socket:

socket.close();

How to use a ServerSocket: ServerSocket server = new ServerSocket( port ); Socket aSocket = server.accept();

The accept method is blocking, it will block the current execution flow. If there is need to process multiple clients at the same time the program must be multithreaded.

As we can observe, opposing UDP, the TCP approach, at least in Java, does not need a crafting of every single packet, there is an abstraction layer that makes it possible to just dump information and let the underlying implementation handle the low-level management.

For more information on TCP go here.

Thank you for reading!

April 2, 2009 at 10:50pm
Tags: Introduction  Java  UDP 

Comments (View)

The connectionless networking protocol

Also known as UDP (User Datagram Protocol), like the title suggests, it does not have a logical idea of connection.

The way it communicates is by datagrams (or messages). The protocol is not able assert any type of confirmation at a transport layer level if a message got thru to the destination. A collateral effect of this is that UDP is a very lightweight protocol, perfect for scenarios where the loss of some information does not break the intended application.

In Java, to implement UDP communication it’s mostly used the following two objects from the java.net.* package: DatagramPacket and DatagramSocket.

The DatagramPacket is used to create a datagram that will be received or sent and configure destination/port in the latter:

DatagramPacket packet = new DatagramPacket( someString.getBytes(), someString.length() );

To configure the destination of the datagram the following methods are used:

packet.setAddress( InetAddress.getByName( someServerName ) ); packet.setPort( port );

InetAddress.getByName is an static method that given a server name like “www.google.com” returns the IP address.

A DatagramPacket can be used to send any type of message that has been converted to an array of byte. There is, however, an UDP protocol 65,507 byte limit to the size of the array.

To extract the information from a received packet the following methods are used:

byte[] info = packet.getData(); int infoLength = packet.getLength();

A DatagramSocket is initialized using the constructor that receives a port which will be used for sending and receiving datagrams:

DatagramSocket socket = new DatagramSocket( port );

The methods used by this object are:

socket.send( DatagramPacket x ); socket.receive( DatagramPacket x );

The receive method is blocking, it will block the current execution flow until it has received a message. To receive a packet, it doesn’t make sense to configure a destination and a port, only a buffer to where the data will be stored like in the declaration of the packet object. Since all the complex ( i.e. Object ) argument passing is by reference, the received packet will overwrite all the information in x.

For more information on UDP go here.

Hope this has been useful.

Thank you for reading!