Tuesday, November 5, 2013

Distributed Computing, Connection Oriented Socket API

In my previous posts, I shared about connection less communication with socket API. This post is about connection oriented communication with socket API.
In the case of connection less communication, the packets are received at the receiver at random. Which means, if you consider packets received consecutively, the collection may contain packets in a random order and may be from many senders.
Connection oriented communication is also called Stream-mode communication where the packets are written to the stream by a sender and the receiver reads these packets from the stream.
In java, to implement Connection Oriented socket communication, two classes are used
1. ServerSocket (to establish and maintain the connection)
2. Socket (for data exchange)

Demo1:
The following program demonstrates a basic Connection Oriented communication between two processes, ConnectionAcceptor and ConnectionRequestor, running on two different hosts. ConnectionAcceptor process accepts a connection from ConnectionRequestor process and sends back a response provided in the command line arguments. ConnectionRequestor process sends a connection request to the ConnectionRequestor process, gets a response and prints the received response.

Code (ConnectionAcceptor):
import java.net.*;
import java.io.*;

/* 
*   ****** CONNECTION ORIENTED SOCKET PROGRAMMING *****
*   Author : @NaveenKumar
*   Program : Connection Acceptor (Server)
*   Date : 29/10/2013
*   File Name    : ConnectionAcceptor.java
*/

public class ConnectionAcceptor 
{
  public static void main(String args[])
  {
     if(args.length != 2)
     {
      System.out.println("Error in required no. of parameters");
     }// end of if
     else
     {
try{
int portNo = Integer.parseInt(args[0]);
String message = args[1];
ServerSocket connectionSocket = new 
                                 ServerSocket(portNo);
System.out.println("Waiting for connection");
Socket dataSocket = connectionSocket.accept();
System.out.println("Connection Accepted");
OutputStream outStream = 
                         dataSocket.getOutputStream();
PrintWriter socketOutput = new PrintWriter(new                            OutputStreamWriter(outStream));
socketOutput.println(message);
socketOutput.flush();
System.out.println("Message sent");
try{
    Thread.sleep(5000);
    System.out.println("Waiting time is over");
}catch(Exception e)
{
e.printStackTrace();
}
socketOutput.println(message);
socketOutput.flush();
dataSocket.close();
System.out.println("Data socket closed");
connectionSocket.close();
System.out.println("connection socket closed");
}catch(Exception ex){
ex.printStackTrace();
}//end of catch
   }//end of else
  }// end of main
}// end of class ConnectionAcceptor

Code (Connection Requestor):
import java.net.*;
import java.io.*;

/* 
*   ****** CONNECTION ORIENTED SOCKET PROGRAMMING *****
*   Author : @NaveenKumar
*   Program : Connection Requestor (client)
*   Date : 29/10/2013
*   File Name           : ConnectionRequestor.java
*/

public class ConnectionRequestor
{
  public static void main(String args[])
  {
    if(args.length != 2)
    {
System.out.println("Insufficient parameters");
    }// end of if
    else
    {
try{
InetAddress acceptorHost =InetAddress.getByName(args[0]);
int acceptorPort = Integer.parseInt(args[1]);
Socket mySocket = new Socket(acceptorHost, acceptorPort);
System.out.println("Connection request granted");
InputStream inStream = mySocket.getInputStream();
BufferedReader socketInput = new BufferedReader(new 
                           InputStreamReader(inStream));
System.out.println("waiting to read");
String message = socketInput.readLine();
System.out.println("Message received:\t"+message);
mySocket.close();
System.out.println("Data Socket closed");
       }catch(Exception ex){
ex.printStackTrace();
       }//end of catch
    }// end of else
  }// end of main
} // end of ConnectionRequestor

Executing Procedure:
1. Deploy the above programs in two different nodes which are connected on a network
2. Open terminal (command prompt) on both the nodes
3. navigate to the above java file locations
4. On terminal 1, javac ConnectionAcceptor.java (press enter),
                          java ConnectionAcceptor 3000  hai (press enter)
5. On the other terminal, javac ConnectionRequestor.java (press enter)
                                      java ConnectionRequestor 192.168.10.1 3000 (press enter)
192.168.10.1 is the IP address of the node that is running the ConnectionAcceptor process and 3000 is the port number on which it is listening.

'hai' is the response send back to the ConnectionRequestor process by ConnectorAcceptor process.

Demo 2:
Now, a modified version of the above ConnectionAcceptor is as follows. The modification provided is that, instead of accepting one single connection, it can accept multiple connections. The ConnectionAcceptor process is not terminated.

for better understanding, the new ConnectionAcceptor is renamed as Server.

Code (Server):
import java.net.*;
import java.io.*;

/* 
*   ****** CONNECTION ORIENTED SOCKET PROGRAMMING *****
*  Author : @NaveenKumar
*  Program : Server
*  Date : 29/10/2013
*  File Name           : Server.java
*/

public class Server 
{
  public static void main(String args[])
  {
    if(args.length != 2)
    {
      System.out.println("Error in required no. of parameters");
    }// end of if
    else
    {
     try{
int portNo = Integer.parseInt(args[0]);
String message = args[1];

ServerSocket connectionSocket = new ServerSocket(portNo);
System.out.println("Waiting for connection");
int i,j;
i = j = 1;
while(i==j)
{
  Socket dataSocket = connectionSocket.accept();
  System.out.println("Connection Accepted");
  OutputStream outStream = dataSocket.getOutputStream();
  PrintWriter socketOutput = new PrintWriter(new 
                    OutputStreamWriter(outStream));
  socketOutput.println(message);
  socketOutput.flush();
  System.out.println("Message sent");
  try{
Thread.sleep(5000);
System.out.println("Waiting time is over");
  }catch(Exception e)
  {
e.printStackTrace();
  }
  socketOutput.println(message);
  socketOutput.flush();

  dataSocket.close();
  System.out.println("Data socket closed");
}
connectionSocket.close();
System.out.println("connection socket closed");
    }catch(Exception ex){
ex.printStackTrace();
    }//end of catch
  }//end of else
 }// end of main
}// end of class Server

Code (Client):
import java.net.*;
import java.io.*;

/* 
*   ****** CONNECTION ORIENTED SOCKET PROGRAMMING *****
*  Author : @NaveenKumar
*  Program : Client
*  Date : 29/10/2013
*  File Name           : Client.java
*/

public class Client
{
  public static void main(String args[])
    {
       if(args.length != 2)
   {
     System.out.println("Insufficient parameters");
   }// end of if
   else
   {
     try{
      InetAddress acceptorHost = InetAddress.getByName(args[0]);
      int acceptorPort = Integer.parseInt(args[1]);
      Socket mySocket = new Socket(acceptorHost, acceptorPort);
      System.out.println("Connection request granted");
      InputStream inStream = mySocket.getInputStream();
      BufferedReader socketInput = new BufferedReader(new 
                                  InputStreamReader(inStream));
      System.out.println("waiting to read");
     String message = socketInput.readLine();
     System.out.println("Message received:\t"+message);
     mySocket.close();
   System.out.println("Data Socket closed");
    }catch(Exception ex){
      ex.printStackTrace();
    }//end of catch
   }// end of else
  }// end of main
} // end of Client

Execution:
One Server process running on a host on a network, multiple Client processes running on multiple hosts on the network.
1. Deploy the above programs in different hosts which are connected on a network
2. Open terminal (command prompt) on both the nodes
3. navigate to the above java file locations
4. On terminal 1, javac Server.java (press enter),
                          java Server 3000  hai (press enter)
5. On the other terminals, javac Client.java (press enter)
                                      java Client 192.168.10.1 3000 (press enter)
192.168.10.1 and 3000 are the IP address and port number of the Server Process.

Try executing multiple clients simultaneously and observe the happenings.
If you dont have multiple hosts available, then for demonstration purpose, you can do execution on localhost itself as demonstrated in the class.


Wednesday, October 30, 2013

Distributed Computing, Socket API Prime Number identification from a list of numbers

In the previous example, we looked into a connection less java Socket API Program. Now, assume that there are 4 nodes in the distributed system and 100 numbers given as input are to be processed (for example, checking if a given number is a prime or not). Now we need a master node to accept this input and proceed with assigning of the work and again displaying the final output. For simplicity, I am giving input as the first 100 natural numbers.
The Setup is assumed to consist of one 5 nodes. One master and others as slaves.
Code: Master.java
import java.net.*;
import java.io.*;
/*
*   ************* SOCKET PROGRAMMING (Master) **************
*Author    : @NaveenKumar
*Program   :To print prime numbers in [1,100]
*Date      : 29/10/2013
*File Name : Master.java
*/
public class Master
{
     public static void main(String args[])
     {
           int num;
           try{
                InetAddress[] receiverHost = {
                             InetAddress.getByName("127.0.0.1"),
                             InetAddress.getByName("127.0.0.1"),
                             InetAddress.getByName("127.0.0.1"),
                             InetAddress.getByName("127.0.0.1")};
                int[] receiverPort = {3000,3010,3020,3030};
                String message;
             //instantiate a datagram socket for sending the data
                DatagramSocket s = new DatagramSocket();
                DatagramSocket s1 = new DatagramSocket(3500);
                byte[] buffer;
                for(int i=1;i<=100;i++)
                {
                     message = Integer.toString(i);
                     buffer = message.getBytes();
                     DatagramPacket p = new             
                     DatagramPacket(buffer,buffer.length,
                            receiverHost[i%4],receiverPort[i%4]);
                     s.send(p);
                }
                s.close();
                byte[] buffer1;
                String msg1;
                for(int i = 0;i<100 i="" o:p="">
                {
                     buffer1 = new byte[10];
                     DatagramPacket p1 = new DatagramPacket
                                                    (buffer1,10);
                     s1.receive(p1);
                     msg1 = new String(buffer1);
                     //num = Integer.parseInt(msg1);
                     if(msg1.charAt(0)!='-')
                           System.out.println("Received: "+msg1);
                }
                s1.close();
           }catch(Exception ex) 
           {
                ex.printStackTrace();
           }//end of catch
     }//end of main
}//end of class

In the above program for Master node,  a list of nodes in the network are provided with the port numbers of respective node on which they are listening. Once the processing of data is done on the other nodes, then the results are then processed on the Master node and displayed. If the number -1 is received from any slave, it is ignored but if a positive integer is received, then it is printed.

Code: Slave.java
import java.net.*;
import java.io.*;

/*
*   ******************** SOCKET PROGRAMMING (SLAVE) **************
*    Author          : @NaveenKumar
*    Date      : 29/10/2013
*    File Name       : Receiver.java
*/

public class Slave
{
     public static void main(String args[])
     {
           System.out.println("Starting Receiver");
           if(args.length!=1)
           {
                System.out.println("Invalid no. of args");
           }
           else{
           int receive_port = Integer.parseInt(args[0]);
           try
           {
                DatagramSocket s = new 
                                   DatagramSocket(receive_port);
                DatagramSocket soc = new DatagramSocket();
                System.out.println("Socket created");
                byte[] buffer = new byte[10];  
                System.out.println("buffer created");
                DatagramPacket p = new DatagramPacket(buffer,10);
                System.out.println("packet created");
                int i,j;
                i=10;
                j=10;
                String msg;
                Slave sl = new Slave();
                while(i==j)
                {
                     s.receive(p);
                     msg = new String(buffer);
                     // process the message
                     sl.process(msg,soc);
                }
                s.close();
           }catch(Exception ex) // end of try and start of catch
           {
                ex.printStackTrace();
           }// end of catch
      }//end of else
     }// end of main
    
     public Slave()
     {
          
     }
     public void process(String msg, DatagramSocket s1)
     {
           String msg1="";
           String msg2 = "";
           String message = msg;
           int res = -1;
           byte[] buffer;
           for(int k=0;k
           {
                if((int)message.charAt(k)<58 amp="" nbsp="" span="">
                                  (int)message.charAt(k)>47) 
                        msg2 += message.charAt(k);
                else 
                        break;
           }
           int num = Integer.parseInt(msg2);
           int temp = 0;
           for(int i=1;i
           {
                if(num%i == 0)
                           temp++;
                if(temp==2)
                     break;
           }
           if(temp==1)
                res = num;
           else
                res = -1;
           try{
                InetAddress receiverHost = 
                             InetAddress.getByName("127.0.0.1");
                int receiverPort = 3500;
                msg1 = Integer.toString(res);
                System.out.println("Msg: "+msg1);
                buffer = msg1.getBytes();
                DatagramPacket p1 = new DatagramPacket(buffer,
                       buffer.length,receiverHost,receiverPort);
                s1.send(p1);
           }catch(Exception ex)
           {
                ex.printStackTrace();
           }// end of catch
     }//end of process method
}// end of class Receiver


In the above code for Slave process, slave process waits for receiving a message from Master process. Once a number is received, it calls process() method with the received message as a parameter to this method. Here in this method, the received data is converted into integer and then checked if it is a prime number of not. If it is a prime number, the number itself is sent back to the Master. If it is not a prime number, then -1 is sent back.

Tuesday, October 29, 2013

Distributed Computing, Socket API

This post is to help my students, in IV year B.Tech (IT), understand a programming facility for IPC, that is, socket API in Distributed Computing. Socket API provides a low level of abstraction for IPC. This API is appropriate if the resources are limited in a Distributed Environment.
In this post I am going to implement a basic Java Socket program first and then I consider a problem that is solved in a distributed environment with IPC programmed with sockets in java.

In the first application, the job here is to send a message to a receiver node from a sender node where, the message is displayed at the receiver to show that the received message is processed. 
The Socket programming implementation of IPC is Asynchronous send and Synchronous receive, because the sender doesn't enter blocking state while sending the message but the receiver will enter into blocking state till the message is received.
The scenario here is, a process Sender is running on a Host A and the other process Receiver is running on Host B.

Code : Sender
---- - ------
import java.net.*;
import java.io.*;
/* 
*   *************** SOCKET PROGRAMMING (SENDER) **************
* Author : @NaveenKumar
* Date : 29/10/2013
* File Name   : Sender.java
*/
public class Sender
{
  public static void main(String args[])
  {
    if(args.length!=3)
    {
      System.out.println("Insufficient parameters");
    }// end of if
    else
    {
      System.out.println("Parameters read");
      try{
       InetAddress receiverHost=InetAddress.getByName(args[0]);
       int receiverPort = Integer.parseInt(args[1]);
       String message = args[2];
  System.out.println("Arguments copied into variables");
  //instantiate a datagram socket for sending the data
       DatagramSocket s = new DatagramSocket();
  System.out.println("Datagram Socket instantiated");
  byte[] buffer = message.getBytes();
       DatagramPacket p = new                  
       DatagramPacket(buffer,buffer.length,
                                  receiverHost,receiverPort);                      System.out.println("Datagram Packet instantiated"); s.send(p);
       s.close();
       }catch(Exception ex) //end of try and beginning of catch
       {
ex.printStackTrace();
       }//end of catch
     }// end of else
  }//end of main
}//end of class


In the above program, the Receiver IP address, Receiver Port number and message to be sent are taken as arguments to main function. Required parameters like Receiver's IP address, Port number, message are set before instantiating the Datagram socket.
After the socket is instantiated (in this case the socket is 's'), a Datagram Packet is instantiated (in this case it is 'p') with the IP address of its receiver, port number and message are bundled into the packet. 
Now, the packet is sent through the socket 's', to the receiver socket.

Code : Receiver
---- - --------
import java.net.*;
import java.io.*;

/* 
* **************** SOCKET PROGRAMMING (RECEIVER) **************
* Author : @NaveenKumar
* Date : 29/10/2013
* File Name   : Receiver.java
*/

public class Receiver
{
  public static void main(String args[])
  {
        System.out.println("Starting Receiver");
   if(args.length!=1)
   {
     System.out.println("Insufficient arguments");
   }// end of it
   else
   {
     System.out.println("Success on number of arguments");
     int receive_port = Integer.parseInt(args[0]);
     try
     {
DatagramSocket s = new DatagramSocket(receive_port);
        System.out.println("Socket created");
byte[] buffer = new byte[10];
System.out.println("buffer created");
DatagramPacket p = new DatagramPacket(buffer,10);
System.out.println("packet created");
s.receive(p);
System.out.println("Received message successfully");
String msg = new String (buffer);
System.out.println(msg);
s.close();
      }catch(Exception ex) // end of try and start of catch
      {
  ex.printStackTrace();
      }// end of catch
    }// end of else
  }// end of main
}// end of class Receiver

In this case of the Receiver process running on Host B, a Datagram Socket is instantiated to facilitate the receive operation, a Datagram Packet is instatitated and when the receive operation is reached, the process is sent to blocked state and set to wait for the message to be received from the Sender.
To show the blocking, checksums are provided at each stage. Once the receive operation is completed, the process is unblocked and continued with the processing of data.

The communication in the above scenario is between two processes Sender and Receiver performing either send or receive operations respectively but any process can send as well as receive data to/from other processes running on same or different hosts. That may be illustrated in the next post.

Hope this is helpful.

Saturday, June 1, 2013

Fee Payment Module

Hi
After the last hello world program in javafx, I started developing an app to check for student fee payment details based on the bill number. Only the interface part is done.

In developing this interface, I have used BorderPane, StackPane, HBox, VBox, TextField, Label, and Button (to toggle fullscreen mode).

The interface displays the college name, department (in this case it is Academic Section), followed by date. There  is a text field that takes the bill number.
A Full screen button to toggle fullscreen.

Hope it is useful for your understanding of javafx.

Source Code:
/**
 * Created with IntelliJ IDEA.
 * User: NaveenKumar
 * Date: 1/6/13
 * Time: 10:16 AM
 */

package FeeReceipt;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;

import java.util.Date;
import java.util.GregorianCalendar;

public class Main extends Application {

    public static void main(String[] args){
        launch(args);
    }

    @Override
    public void start(final Stage stage) throws Exception {
        stage.setFullScreen(true);

        BorderPane border = new BorderPane();
        VBox vbox_top = new VBox();
        vbox_top.setAlignment(Pos.CENTER);
        vbox_top.setPadding(new Insets(10,10,10,10));
        vbox_top.setStyle("-fx-background-color: #A9D0F5");

        // College Name
        Label colg_name = new Label();
        colg_name.setText("XYZ College of Engineering");
        colg_name.setFont(Font.font("Calibri", FontWeight.BOLD, 35));

        // Academic Section
        Label academic_section = new Label();
        academic_section.setText("Academic Section");
        academic_section.setFont(Font.font("Arial", FontWeight.BOLD, 30));

        //Fee Receipt
        Label fee_receipt = new Label();
        fee_receipt.setText("(Fee Receipt)");
        border.setTop(vbox_top);
        fee_receipt.setFont(Font.font("Verdana", FontWeight.BOLD, 20));

        HBox hbox1 = new HBox();
        //Bill No
        Label bill_no = new Label();
        bill_no.setText("Bill No:");
        bill_no.setFont(Font.font("Verdana", FontWeight.NORMAL, 18));

        //Bill Number Text field
        TextField bno = new TextField();
        bno.setPrefColumnCount(8);

        hbox1.getChildren().addAll(bill_no,bno);

        //date
        Label dt = new Label();
        dt.setText("Date:");

        StackPane dt_stack = new StackPane();
        Rectangle dt_rect = new Rectangle(150.0,25.0);
        dt_rect.setFill(new LinearGradient(0,0,0,1,true, CycleMethod.NO_CYCLE,
                new Stop[]{
                        new Stop(0, Color.web("#4977A3")),
                        new Stop(0.5,Color.web("#B0C6DA")),
                        new Stop(1,Color.web("9CB6CF")),
                }));
        dt_rect.setStroke(Color.web("#D0E6FA"));
        dt_rect.setArcHeight(3.5);
        dt_rect.setArcWidth(3.5);

        Date dt_today = new Date();
        String dt_today1 = dt_today.toString().substring(4,10)+" "+dt_today.toString().substring(dt_today.toString().length()-4,dt_today.toString().length());
        Text dt_text = new Text("  "+dt_today1);
        dt_text.setFont(Font.font("verdana", FontWeight.BOLD, 18));
        dt_text.setFill(Color.WHITE);
        dt_text.setStroke(Color.web("#7080A0"));
        dt_stack.getChildren().addAll(dt_rect,dt_text);
        dt_stack.setAlignment(Pos.CENTER_LEFT);

        //stack pane for full screen button
        StackPane stack = new StackPane();


        ImageView fs = new ImageView(
                new Image(Main.class.getResourceAsStream("graphics/view-fullscreen.png")));
        Button fullScrn = new Button();
        fs.setFitHeight(30);
        fs.setFitWidth(30);
        fs.setPreserveRatio(true);

        fullScrn.setGraphic(fs);

        //full screen event handler
        fullScrn.setOnAction(new EventHandler() {
            @Override
            public void handle(ActionEvent e) {
                stage.setFullScreen(!stage.isFullScreen());
            }
        });

        stack.getChildren().addAll(fullScrn);
        stack.setAlignment(Pos.CENTER_RIGHT);
        StackPane.setMargin(fullScrn,new Insets(0,10,0,0));
        // end of stack pane


        hbox1.getChildren().addAll(stack);
        HBox.setHgrow(stack, Priority.ALWAYS);

        vbox_top.getChildren().addAll(colg_name, academic_section, fee_receipt,dt_stack,hbox1);

        Scene scene = new Scene(border);
        stage.setScene(scene);
        stage.setTitle("Fee Payment");
        stage.show();
    }
}

OUTPUT:


Feel free to leave a comment. Thanks for visiting. Have a nice day.

Thursday, May 30, 2013

JavaFX Hello World

This is my first JavaFX application. It is kinda similar to the first Hello World application in the tutorials but I made a few modifications (not bigger modifications but a considerable ones).
Hope you guys enjoy coding in fx.

SOURCE CODE (HELLO WORLD)
package sample;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;


public class Main extends Application{
    public static void main(String[] args)
    {
        System.out.println("Launching Hello World Application");
        launch(args);
    }
    @Override
    public void start(final Stage primaryStage) {
        System.out.println("Preparing the stage");
        primaryStage.setTitle("Hello World");
        System.out.println("Title set to Hello World");
        System.out.println("Creating a new button and setting button text to Say 'Hello World'");
        Button btn = new Button();
        btn.setText("Say 'Hello World'");
        System.out.println("Creating event handler for Hello World Button");
        btn.setOnAction(new EventHandler() {

            @Override
            public void handle(ActionEvent event) {
                System.out.println("Hello World");
            }

        });
        System.out.println("Creating another Button to exit");
        Button btn_exit = new Button();
        btn_exit.setText("Exit");
        System.out.println("Creating event handler for exit button");
        btn_exit.setOnAction(new EventHandler() {
            @Override
            public void handle(ActionEvent actionEvent) {
                System.out.println("Closing the applicaion");
                primaryStage.close();
            }
        });

        GridPane grid = new GridPane();
        grid.setAlignment(Pos.CENTER);
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(25,25,25,25));
        Scene scene = new Scene(grid,300,275);

        grid.add(btn,0,1);
        grid.add(btn_exit,1,1);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

}

OUTPUT SNAPSHOTS:



Keep visiting for more posts.