Monday, April 4, 2011

Java Synchronized Threads

To understand the concept of synchronized threads, I have written the following sample classes. The java class, SyncThread, is implemented using Synchronized run method, while the second doesn't use a Synchronized method. In the SyncTest, two objects of the SyncThread are created. Both of the objects tries to access the same method, i.e, run().

The possible outputs for the synchronized and unsynchronized 'run' is given below the code.




/*
* Thread using Synchronized method
*/

class SyncThread implements Runnable {
Thread t;
static int count = 0;

SyncThread(String tName) {
t = new Thread(this, tName);
}
synchronized public void run() {
count++;
System.out.println(t + " count : " + count);
}
}



In the above code, count is incremented inside a synchronized method. Let's consider this area as a critical region. Using a synchronized method ensures that the region is handled by a monitor (semaphore). So, once an object accesses this method, no other objects will be able to access it.


/*
* Thread without using Synchronized method
*/
class UnSyncThread implements Runnable {
Thread t;
static int count = 0;

UnSyncThread(String tName) {
t = new Thread(this, tName);
}

public void run() {
count++;
System.out.println(t + " count : " + count);
}
}


Since the above code doesn't implement a synchronized 'run', it could result in the Output Case 1 (see the bottom of the page for the outputs). A thread could be preempted while it is still inside the 'run' method. This could create a race condition (as given in the output).





/*
* CLass to test the SyncThreads.
*/
public class SyncTest {
public static void main(String args[]) {
SyncThread st2 = new SyncThread("st2");
SyncThread st1 = new SyncThread("st1");

/* Try declaring the below ones
* for testing unsynchronized threads
*/
//UnSyncThread st1 = new UnSyncThread("st1");
//UnSyncThread st2 = new UnSyncThread("st2");

st1.t.start();
st2.t.start();
}
}



Output Case 1:
Thread[st1,5,main] count : 2
Thread[st2,5,main] count : 2

Output Case 2 : ( with synced run methods )
Thread[st1,5,main] count : 1
Thread[st2,5,main] count : 2

Output Case 3: ( with synced run methods )
Thread[st2,5,main] count : 2
Thread[st1,5,main] count : 1

Monday, August 9, 2010

Multi-threaded HTTP Server

My earlier post on creating a single threaded HTTP/1.0 Server using Java gave an idea about how to implement an HTTP server. This post is an extension to the same program. I have implemented a Multi-threaded version of the same server. The source code is given below.

Implementation
A new thread is spawned upon receiving a connection request from a client. This socket is used to transfer data between these two end-systems. Since the server implements HTTP/1.0, the connection is terminated after the request is satisfied by the server.

The code is available here.

Multi-threaded server

/*
* Coded By: Rahul Krishnan
*/

import java.net.*;
import java.io.*;
import java.util.*;
import java.util.concurrent.*;

class MTServer implements Runnable {
// Socket available to all the methods in the class.
private Socket connectionSocket;

// Constructor.
MTServer (Socket sock) {
connectionSocket = sock;
}

// Main starts here.
public static void main(String argv[]) throws Exception {
// Listen to the client connection.
ServerSocket listenSocket = new ServerSocket(4444);

// Spawn threads for all the new connections.
while (true) {
Socket connectionSocket = listenSocket.accept();
Thread T = new Thread(new MTServer(connectionSocket));
T.start();
}
}

// Thread code.
public void run() {
String httpReqMsg = null; // Strores the request from client.
String fileName = null; // Stores the file name to be fetched.
BufferedReader inFromClient = null; // Input Stream - from the client.
DataOutputStream outToClient = null;// Output Stream - to client.
FileInputStream inFile = null; // Input Stream - from file.

try {
inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
outToClient = new DataOutputStream(
connectionSocket.getOutputStream());

// Read the request from client.
httpReqMsg = inFromClient.readLine();
}
catch (IOException exception) {
exception.printStackTrace();
}

StringTokenizer tokenizedLine = new StringTokenizer(httpReqMsg);
// Extract the file name.
if (tokenizedLine.nextToken().equals("GET")) {
fileName = tokenizedLine.nextToken();

// Process the file name.
if (fileName.startsWith("/") == true) {
// Extract the portion after '/' in the file name.
fileName = fileName.substring(1);
}

// Access the file.
File file = new File(fileName);
int numOfBytes = (int) file.length();

byte[] fileInBytes = new byte[numOfBytes];

try {
inFile = new FileInputStream(fileName);
}
catch (FileNotFoundException exception) {
exception.printStackTrace();
}

try {
inFile.read(fileInBytes);
}
catch (IOException exception) {
exception.printStackTrace();
}

try {
// Server response message starts.
outToClient.writeBytes("HTTP/1.0 200 OK\r\n");

// Send the content type.
if (fileName.endsWith(".jpg")) {
outToClient.writeBytes("Content-Type: image/jpeg\r\n");
}
if (fileName.endsWith(".gif")) {
outToClient.writeBytes("Content-Type: image/gif\r\n");
}
// Send the content length.
outToClient.writeBytes("Content-Lenght: " + numOfBytes + "\r\n");

// Important : comply with the HTTP reply format.
outToClient.writeBytes("\r\n");
// Write the file into the output stream.
outToClient.write(fileInBytes, 0, numOfBytes);
connectionSocket.close();
}
catch (IOException exception) {
exception.printStackTrace();
}
}
}
}

Sunday, August 1, 2010

Single-threaded HTTP Server

An HTTP Server is an application layer process which accepts and responds to client requests for web objects (pages, images, videos etc.). To explain the process in simple terms, I have included the source code for a basic single threaded server.

HTTP Server
This server will establish TCP connection with the requesting clients. Once done, it can accept "GET" HTTP messages from these clients. The server processes it (parses the request message to extract the file url). This server can accept only jpg and gif file requests. If the file is found in the server, an HTTP response message is generated and send back to the client. After this, the server closes the connection with the client.

Implementation Details
The server is an HTTP 1.0 implementation for it works on non-persistent connection to send and receive data.

I have attached the source code below. You can also access it from here.


/*
* Coded by: Rahul Krishnan
* Description:
* A basic single threaded HTTP server program. It can accept
* GET messages from the clients requesting for jpg and gif
* files. The server then sends the response as HTTP packets.
*/

import java.net.*;
import java.io.*;
import java.util.*;

class WebServer {
public static void main(String argv[]) throws Exception {
String httpReqMsg; // Strores the request from client.
String fileName; // Stores the file name to be fetched.

ServerSocket listenSocket = new ServerSocket(4444);
Socket connectionSocket = listenSocket.accept();

BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));

DataOutputStream outToClient = new DataOutputStream(
connectionSocket.getOutputStream());

// Read the request from client.
httpReqMsg = inFromClient.readLine();

StringTokenizer tokenizedLine = new StringTokenizer(httpReqMsg);

// Extract the file name.
if (tokenizedLine.nextToken().equals("GET")) {
fileName = tokenizedLine.nextToken();

// Process the file name.
if (fileName.startsWith("/") == true) {
// Extract the portion after '/' in the file name.
fileName = fileName.substring(1);
}

// Access the file.
File file = new File(fileName);
int numOfBytes = (int) file.length();

byte[] fileInBytes = new byte[numOfBytes];
FileInputStream inFile = new FileInputStream(fileName);

inFile.read(fileInBytes);

// Server response message starts.
outToClient.writeBytes("HTTP/1.0 200 OK\r\n");

// Send the content type.
if (fileName.endsWith(".jpg")) {
outToClient.writeBytes("Content-Type: image/jpeg\r\n");
}
if (fileName.endsWith(".gif")) {
outToClient.writeBytes("Content-Type: image/gif\r\n");
}
// Send the content length.
outToClient.writeBytes("Content-Lenght: " + numOfBytes + "\r\n");

// Important : comply with the HTTP reply format.
outToClient.writeBytes("\r\n");
// Write the file into the output stream.
outToClient.write(fileInBytes, 0, numOfBytes);
connectionSocket.close();
}
else System.out.println("Bad Request Message");
}
}

Sunday, July 18, 2010

File Database I/O

I have enrolled to the Database Management Systems (DBMS) course in the present semester. The first lab assignment was to model a file DB - use file to store, retrieve, modify and delete structured data (name, roll number). This assignment was to understand the difficulties involved in managing structured data using the conventional file system.

The program
The C program gives options to insert, retrieve and delete data from a file DB - db.dat. The source code is available here.

There is comment on the important sections of the code and I hope you could understand most of it.


/*
* Coded By: Rahul Krishnan
*
* Description:
* Program implementing basic Database I/O
* using file system instead of DBMS. This
* is to show that files are not designed
* to store structured and related data.
*/

#include
#include
#include

int
main() {
char name[10];
int choice, roll, key, found = 0;
FILE *f_ptr; // File pointer to db.dat
FILE *n_ptr; // File pointer to newdb.dat

while (1) {
printf("\n***** FILE DB Menu ******");
printf("\n1. Enter data\n2. Display All\n3. Search by roll\n4. Delete by roll\n5. Exit");
printf("\nEnter your choice : ");
scanf("%d", &choice);

switch (choice) {
case 1:
// Adds an entry into the file DB.
f_ptr = fopen("db.dat", "a");

printf("Enter the : ");

// Read from stdin and write to file.
fscanf(stdin, "%d %s", &roll, &name);
fprintf(f_ptr, "%d %s\n", roll, name);

fclose(f_ptr);
break;
case 2:
// Displays all the contents of the file DB.
printf("\nShowing DB\n----------\n");
f_ptr = fopen("db.dat", "r");

// Read from "db.dat" and write to stdout.
while ((fscanf(f_ptr, "%d %s", &roll, &name)) != EOF) {
printf("%d %s\n", roll, name);
}

fclose(f_ptr);
break;
case 3:
// Search the file DB with roll as the key.
printf("Enter the roll to be searched : ");
scanf("%d", &key);

f_ptr = fopen("db.dat", "r");
found = 0; // Set to 1 if record found.

// Search through all the entries comparing the key.
while ((fscanf(f_ptr, "%d %s", &roll, name)) != EOF) {
if (roll == key) {
printf("\nRecord Found\n-------------\n%d %s\n-------------", roll, name);
found = 1;
}
}

if (found != 1) {
printf("\nRecord NOT found !!");
}
fclose(f_ptr);

break;
case 4:
// Deletes a file DB entry based on the roll as key.
printf("Enter the ROLL of the entry to be deleted : ");
scanf("%d", &key);

f_ptr = fopen("db.dat", "r");
n_ptr = fopen("newdb.dat", "w");

found = 0; // Set to 1 if record found.

// Copy all the entries except the one with the key
// to a new file "newdb.dat", which is rename later to
// "db.dat".
while ((fscanf(f_ptr, "%d %s", &roll, name)) != EOF) {
if (roll != key) {
fprintf(n_ptr,"%d %s\n", roll, name);
}
if (roll == key)
found = 1;
}

// To rename the newdb.dat to db.dat.
fclose(f_ptr);
fclose(n_ptr);
remove("db.dat");
rename("newdb.dat", "db.dat");

// If the key is not found, then output NOT found.
// But the file is already duplicated and the file names
// changed, even if the key is not found.
if (found != 1) {
printf("\nRecord NOT found !!");
}

break;
case 5:
exit(0);
default:
printf("\nInvalid Choice");
}
}
return 0;
}

Saturday, July 17, 2010

Socket Programming with UDP in Java

Continuation to my post on TCP socket program, this is an example of using the UDP protocol at the Transport layer to implement the same process. The code is available here.

Most of the concepts covered in my earlier post on TCP is repeated here. But there are some striking difference between TCP and UDP which are summarized below.

1) UDP is connection-less - There is no handshaking before sending the datagrams.

2) It is message oriented - Each packet contains the information about the destination (IP address and the port number). UDP doesn't give guarantees delivery of the packet (unreliable) or the order in which the packets are delivered. (Contrast this with the reliable data transfer of TCP and the byte-streams model of data transfer between the client and server).

3) In the text (Computer Networking: A top down approach), the authors have compared the UDP to a taxi-service. Each taxi driver must be informed about the destination of the taxi (in UDP - IP and port).

The source code is extensively commented and you might not have difficulties understanding it.

The Client

/*
* Coded by: Rahul Krishnan
*
* Description: A UDP based client which gets input form
* the user and sends the sentence to the server. It
* receives the capitalized form of the sentence and
* prints it on standard output.
*/

import java.io.*;
import java.net.*;

class UDPClient {
public static void main(String argv[]) throws Exception {
String sentence; // User input sentence.
String modifiedSentence; // Capitalized sentence from server.

// Bind to the standard input stream.
BufferedReader fromUser = new BufferedReader(
new InputStreamReader(System.in));

// Initializing the client socket.
DatagramSocket clientSocket = new DatagramSocket();

InetAddress IPAddress = InetAddress.getByName("localhost");

byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];

System.out.print("Send Msg> ");

sentence = fromUser.readLine();
sendData = sentence.getBytes();

// Initialize the datagram packet to be send.
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 4444);

// Send the datagram packet through the socket.
clientSocket.send(sendPacket);

// Initialize a datagram packet to received the server reply.
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);

clientSocket.receive(receivePacket);
modifiedSentence = new String(receivePacket.getData());

System.out.println("Server reply> " + modifiedSentence);
clientSocket.close();
}
}


The Server

/*
* Coded by: Rahul Krishnan
*
* Description: A UDP based server which takes in
* packets from client and the sends back the
* capitalized form of the sentence to the client.
*/

import java.net.*;

class UDPServer {
public static void main(String argv[]) throws Exception {
String recSentence; // Sentence received from client.
String capSentence; // Capitalized sentence.

DatagramSocket serverSocket = new DatagramSocket(4444);

byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];

DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);

while (true) {
System.out.println("Waiting for packets...");
serverSocket.receive(receivePacket);

recSentence = new String(receivePacket.getData());
System.out.println("Client Sent> " + recSentence);

// Extract the client IP address from the packet.
InetAddress clientAddress = receivePacket.getAddress();
int port = receivePacket.getPort();

capSentence = recSentence.toUpperCase();
sendData = capSentence.getBytes();

DatagramPacket sendPacket = new DatagramPacket(
sendData, sendData.length, clientAddress, port);
serverSocket.send(sendPacket);
}
}
}

Thursday, July 15, 2010

Socket Programming using TCP in Java

I am working out some basic network programming examples and assignments from Computer Networks:A Top-Down Approach (James F Kurose and Keith W Ross). This post is regarding the implementation of a simple Client Server application using TCP at the Transport layer. The program is coded in Java. I have made the source code available here.

Source Code for the TCP Client-Server model in Java


The program is extensively commented, and I hope you could find your way through this code. This is aimed at Beginners (Just like me) who are newly introduced to the concepts of socket programming.

Program
The program implements a client-server application. The client accepts a sentence from the user through the keyboard (standard input). It then sends this string to the server through the socket output stream. The server receives this and then capitalizes the sentence. This modified string is then send to the client through the socket output stream of the server. Upon receiving the capitalized string from the server, the client outputs it to the terminal (standard out).

Concepts Covered
This program covers a lot of basic concepts regarding network programming.

1) The Client-Server architecture.

2) The socket as the two end points of connection between client and server.

3) Input and Output stream associated with the standard I/O (keyboard/terminal) and
also associated with the network sockets.

4) The abstraction provided by treating the network architecture in layers. Our codes are at the Application layer. It uses the services provided by the Transport layer - here, TCP.

This program gives an introduction to the basics of network programming at the Application layer using TCP.

The Client

/*
* Coded by: Rahul Krishnan
* File Name: TCPClient.java
*
* Description:
* A simple client-server program using TCP
* at the Transport layer to initiate a reliable
* data transport connection. Client sends a sentence
* to the server. The server sends back capitalized
* sentence. This is output to stdout.
*
*/

import java.io.*;
import java.net.*;

class TCPClient {
public static void main(String argv[]) throws Exception{
String sentence; // Lowercase sentence from user.
String modifiedSentence; // Stores uppercase reply from server.

// Input stream - from user keyboard.
BufferedReader fromUser = new BufferedReader(
new InputStreamReader(System.in));

// Creates the Client socket and binds to the server
// at localhost, port 4444
Socket clientSocket = new Socket("localhost", 4444);

// Output stream to send the sentence through this.
DataOutputStream toServer = new DataOutputStream(clientSocket.getOutputStream());

// Input stream to read the capitalized sentence from server.
BufferedReader fromServer = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));

System.out.print("Client> ");

sentence = fromUser.readLine();
toServer.writeBytes(sentence + '\n');

modifiedSentence = fromServer.readLine();
System.out.println("Server>" + modifiedSentence);
clientSocket.close(); // TCP Client sends the close message to server.
}
}


The Server

/*
* Coded by: Rahul Krishnan
* File Name: TCPServer.java
*
* Description:
* A simple client-server program using TCP
* at the Transport layer to initiate a reliable
* data transport connection. The server takes in
* a sentence from client and sends back the
* capitalized version of it.
*
*/
import java.io.*;
import java.net.*;

class TCPServer {
public static void main(String argv[]) throws Exception {
String clientSentence; // Stores sentence sent by client.
String upperCaseSentence; // Uppercase sentence.

// Creates a server socket, which waits for clients
// to initiate connection.
ServerSocket welcomeConnection = new ServerSocket(4444);

while (true) {
System.out.println("Waiting for clients to connect....");

// Creates a new socket when a client contacts
// the server for the first time.
Socket connection = welcomeConnection.accept();

System.out.println("Client Connected.");

BufferedReader fromClient = new BufferedReader(
new InputStreamReader(connection.getInputStream()));

DataOutputStream toClient = new DataOutputStream(
connection.getOutputStream());


clientSentence = fromClient.readLine();
System.out.println("Client sent: " + clientSentence);
upperCaseSentence = clientSentence.toUpperCase() + '\n';

toClient.writeBytes(upperCaseSentence);
}
}
}

Post inspired by the simplicity of explanation provided in the text book that I had referred - Authors: Kurose and Ross

Tuesday, July 13, 2010

Tower of Hanoi

Tower of Hanoi is an old and popular problem. The description of the problem is given here - http://en.wikipedia.org/wiki/Tower_of_Hanoi. The solution for this problem can be designed in various ways, few of which are listed in the above wiki page. I have coded a recursive solution to solve the problem. You can find many other solutions in the web as well.

The aim of coding for this particular solution is inspired by the SICP (Structure and Interpretation of Computer Programs) MIT video lectures by Prof. Abelson and Gerald Jay. The aim is to understand the recursive nature of the program.

The program is available at my bitbucket collection - click here (takes you to the page containing the code).

In order to understand the recursive nature of the program. you can compile it with debugging symbols -
gcc -g towers_of_hanoi.cpp


and then use the gdb debugger (learn it) to trace through the different stacks (a, b, c).
gdb a.out


Also, use backtrace (bt) command in gdb to trace through the system stack to get a better understanding of how the code implements the solution.