Program 12 (Java)



12.Write a program for congestion control using leaky bucket algorithm.


The main concept of the leaky bucket algorithm is that the output data flow remains constant despite the variant input traffic, such as the water flow in a bucket with a small hole at the bottom. In case the bucket contains water (or packets) then the output flow follows a constant rate, while if the bucket is full any additional load will be lost because of spillover. In a similar way if the bucket is empty the output will be zero. From network perspective, leaky bucket consists of a finite queue (bucket) where all the incoming packets are stored in case there is space in the queue, otherwise the packets are discarded. In order to regulate the output flow, leaky bucket transmits one packet from the queue in a fixed time (e.g. at every clock tick). In the following figure we can notice the main rationale of leaky bucket algorithm, for both the two approaches (e.g. leaky bucket with water (a) and with packets (b)).

While leaky bucket eliminates completely bursty traffic by regulating the incoming data flow its main drawback is that it drops packets if the bucket is full. Also, it doesn’t take into account the idle process of the sender which means that if the host doesn’t transmit data for some time the bucket becomes empty without permitting the transmission of any packet.





package bucket;

import java.util.*;



public class Bucket {



    static void solution(int pktsize, int output) {

        int buketsize = 512;

        if (pktsize > buketsize) {

            System.out.println("Bucket overflow");

        } else {

            while (pktsize > output) {

                System.out.println(output + "bytes outputed");

                pktsize = pktsize - output;

            }

            if (pktsize > 0) {

                System.out.println(pktsize + "bytes outputed");

            }

        }

    }



    public static void main(String[] args) {

        int output, pktsize, n;

        Scanner read = new Scanner(System.in);

        Random rand = new Random();

        System.out.println("Enter output rate");

        output = read.nextInt();

        System.out.println("Enter the number of packets");

        n = read.nextInt();

        for (int i = 1; i <= n; i++) {

            pktsize = rand.nextInt(1000);

            System.out.println("packetno: " + i + " packetsize=" + pktsize);

            solution(pktsize, output);

        }

    }

}



Sample output:

Run1:

Enter output rate

100

Enter the number of packets

5

packetno: 1 packetsize=564

Bucket overflow

packetno: 2 packetsize=735

Bucket overflow

packetno: 3 packetsize=615

Bucket overflow

packetno: 4 packetsize=129

100bytes outputed

29bytes outputed

packetno: 5 packetsize=773

Bucket overflow

Program 11 (Java)




11.WRITE A PROGRAM FOR SIMPLE RSA ALGORITHM TO ENCRYPT AND DECRYPT THE DATA.

RSA is an example of public key cryptography. It was developed by Rivest, Shamir and Adelman. The RSA algorithm can be used for both public key encryption and digital signatures. Its security is based on the difficulty of factoring large integers.
The RSA algorithm's efficiency requires a fast method for performing the modular exponentiation operation. A less efficient, conventional method includes raising a number (the input) to a power (the secret or public key of the algorithm, denoted e and d, respectively) and taking the remainder of the division with N. A straight-forward implementation performs these two steps of the operation sequentially: first, raise it to the power and second, apply modulo. The RSA algorithm comprises of three steps, which are depicted below:
Key Generation Algorithm:
Ø Generate two large random primes, p and q, of approximately equal size such that their product n = p*q
Ø Compute n = p*q and Eulers totient function (φ) phi(n) = (p-1)(q-1).
Ø Choose an integer e, 1 < e < phi, such that gcd(e, phi) = 1.
Ø Compute the secret exponent d, 1 < d < phi, such that e*d ≡ 1 (mod phi).
Ø The public key is (e, n) and the private key is (d, n). The values of p, q, and phi should also be kept secret.

Encryption:
Sender A does the following:
Ø Using the public key (e,n)
Ø Represents the plaintext message as a positive integer M
Ø Computes the cipher text C = M^e mod n.
Ø Sends the cipher text C to B (Receiver).

Decryption:
Recipient B does the following:
Ø Uses his private key (d, n) to compute M = C^d mod n.
Ø Extracts the plaintext from the integer representative m.

RSA KEY GENERATION

RSA.java

package rsa;



import java.math.BigInteger;

import java.util.Random;

import java.util.Scanner;



public class RSA {



    public static void main(String[] args) {



        // Each public and private key consists of an exponent and a modulus

        BigInteger n;             // n is the modulus for both the private and public keys

        BigInteger e;             // e is the exponent of the public key

        BigInteger d;             // d is the exponent of the private key



        int bitlength = 512;

        Random r = new Random();



         // Step 1: Generate two large random primes.

         // We use 512 bits here, but best practice for security is 2048 bits.

         // Change 512 to 2048, recompile, and run the program again and you will

         // notice it takes much longer to do the math with that many bits.

        BigInteger p = BigInteger.probablePrime(bitlength, r);

        BigInteger q = BigInteger.probablePrime(bitlength, r);

       

         // Step 2: Compute n by the equation n = p * q.

        n = p.multiply(q);           

       

         // Step 3: Compute phi(n) = (p-1) * (q-1)

        BigInteger phi = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));             

       

         // Step 4: Select a small odd integer e that is relatively prime to phi(n).

         // By convention the prime 65537 is used as the public exponent.

        e = new BigInteger("65537");   

       

         // Step 5: Compute d as the multiplicative inverse of e modulo phi(n).

        d = e.modInverse(phi);



        Scanner in = new Scanner(System.in);

        String s;



         // Enter a simple message to be Encrypted

        System.out.println("Enter the plain text:");

        s = in.nextLine();

        

         //m is the byte representation of the message to be encrypted

        BigInteger m = new BigInteger(s.getBytes());



         // Step 8: To encrypt a message m compute c = m^e (mod n)

        BigInteger c = m.modPow(e, n);    



         // Step 9: To decrypt a message c compute m = c^d (mod n)

        BigInteger decrypt = c.modPow(d, n);

        String decryptedText = new String(decrypt.toByteArray());                   // Decode to a string



        //Display encrypted and Decrypted Text

        System.out.println("Encrypted text = " + c);

        System.out.println("Decrypted text = " + decryptedText);

    }

}

Sample Output

Run 2: (with 512 bit length)

Enter the plain text:

Hi

Encrypted text = 50103541608902977714830787067336423528693428112542451321662351307703238988804091377813045118337788875236867053906253106107774066498343223025242498039945783616334368008373436765270106440836251272261312958541836420077143796150889590605720718009223754637616515096158219963336603732720981018779883280372434260244

Decrypted text = Hi

BUILD SUCCESSFUL (total time: 2 seconds)

Program 10 (Java)



10.   Write a program on datagram socket for client/server to display the messages on client side, typed at the server side.


A datagram socket is the one for sending or receiving point for a packet delivery service. Each packet sent or received on a datagram socket is individually addressed and routed. Multiple packets sent from one machine to another may be routed differently, and may arrive in any order.

Udps.java

package udps;



import java.util.Scanner;

import java.net.*;

import java.io.*;



public class Udps {

    public static void main(String[] args) {

        DatagramSocket skt = null;

        String ch;

        Scanner input = new Scanner(System.in);

        try {

           skt = new DatagramSocket(6788);  

            byte[] buffer = new byte[1000];     
            while (true) {          

                DatagramPacket request = new DatagramPacket(buffer, buffer.length);

                skt.receive(request);

                System.out.print("enter the data:  ");

                ch = input.nextLine();

                byte[] sendMsg = (ch + " -> server processed").getBytes();

               

                DatagramPacket reply = new DatagramPacket(sendMsg, sendMsg.length, request.getAddress(), request.getPort());

                skt.send(reply);

            }

       } catch (Exception ex) {



        }

    }

}

Udpc.java

package udpc;

import java.util.Scanner;

import java.net.*;

import java.io.*;



public class Udpc {

    public static void main(String[] args) {

        DatagramSocket skt;

        try {

            skt = new DatagramSocket();

            String msg = "text message";

            byte[] b = msg.getBytes();

            InetAddress host = InetAddress.getByName("127.0.0.1");

            int serverSocket = 6788;

            DatagramPacket request = new DatagramPacket(b, b.length, host, serverSocket);

            skt.send(request);

            byte[] buffer = new byte[1000];

            DatagramPacket reply = new DatagramPacket(buffer, buffer.length);

            skt.receive(reply);

            System.out.println("Client received: " + new String(reply.getData()));

            skt.close();

        } catch (Exception ex) {

        }

    }

}

Program 9 (Java)


9.    Using TCP/IP sockets, write a client – server program to make the client send the file name and to make the server send back the contents of the requested file if present.

      Socket is an interface which enables the client and the server to communicate and pass on information from one another. Sockets provide the communication mechanism between two computers using TCP. A client program creates a socket on its end of the communication and attempts to connect that socket to a server. When the connection is made, the server creates a socket object on its end of the communication. The client and the server can now communicate by writing to and reading from the socket.
Source Code: Server


Server.java

package server;

import java.net.*;

import java.io.*;



public class Server {

    public static void main(String[] args)throws IOException {

       try

        {

            //The server creates a ServerSocket object, denoting which port number communication is to occur on.

            ServerSocket sersock=new ServerSocket(4000);

            System.out.println("server ready for connection");



            /*The server invokes the accept() method of the ServerSocket class. This method waits until a client   connects to the server on the given port.*/

            Socket sock=sersock.accept();

            System.out.println("connection established waiting for chatting");





            // reading the file name from client

            InputStream istream=sock.getInputStream();

            BufferedReader fileRead=new BufferedReader(new InputStreamReader(istream));

            String fname=fileRead.readLine();

           

            // reading file contents

            BufferedReader ContentRead=new BufferedReader(new FileReader(fname));



            // keeping output stream ready to send the contents

            OutputStream ostream=sock.getOutputStream();

            PrintWriter pwrite=new PrintWriter(ostream,true);

            String str;

            while((str=ContentRead.readLine())!=null) // reading line-by-line from file

            {

                pwrite.println(str); // sending each line to client

            }



            // closing network sockets

            sock.close();

            sersock.close();

            pwrite.close();

            fileRead.close(); 

        }

        catch(Exception e)

        {

            System.out.println("an error occured while opening");

        }

    }

 }

Client.java

package client;

import java.net.*;

import java.io.*;



public class Client {

    public static void main(String[] args)throws Exception {

       //client creates a Socket object, specifying the server name and the port number to connect to.

        Socket sock=new Socket("127.0.0.1",4000);



        System.out.println("enter file name");

        /*reading from keyboard (keyRead object)using input stream  connecting the BufferedReader stream with the InputStreamReader stream for reading the line by line data from the keyboard.*/

        //or as commented below use scanner object

       BufferedReader keyread=new BufferedReader(new InputStreamReader(System.in));

       String fname=keyread.readLine();

      //  Scanner scan=new Scanner(System.in);

      //  String fname=scan.nextLine();

       

try{

             // sending the file name to server. Uses PrintWriter

            /*getOutputStream(). This method returns an OutputStream where the data can be written and throws the appropriate exception if it cannot do so.*/

            OutputStream ostream=sock.getOutputStream();

            PrintWriter pwrite=new PrintWriter(ostream,true);

            pwrite.println(fname);

           

            // receiving the contents from server.  Uses input stream

            /*This method returns an InputStream representing the data and throws the appropriate exception if it cannot do so.*/

            InputStream istream=sock.getInputStream();

            BufferedReader socketRead=new BufferedReader(new InputStreamReader(istream));



            String str;

            // reading line-by-line

            while((str=socketRead.readLine())!=null)

            {

                System.out.println(str);

            }

            // closing network sockets

            pwrite.close();             socketRead.close();             keyread.close();

          }

        catch(Exception e)

        {

            System.out.println("an error occured while opening");

        }

    }

}   

Program 8 (Java)



8.      Write a program to find the shortest path between vertices using bellman-ford algorithm.

Distance Vector Algorithm is a decentralized routing algorithm that requires that each router simply inform its neighbors of its routing table. For each network path, the receiving routers pick the neighbor advertising the lowest cost, then add this entry into its routing table for re-advertisement. To find the shortest path, Distance Vector Algorithm is based on one of two basic algorithms: the Bellman-Ford and the Dijkstra algorithms.
Routers that use this algorithm have to maintain the distance tables (which is a one- dimension array -- "a vector"), which tell the distances and shortest path to sending packets to each node in the network. The information in the distance table is always up date by exchanging information with the neighboring nodes. The number of data in the table equals to that of all nodes in networks (excluded itself). The columns of table represent the directly attached neighbors whereas the rows represent all destinations in the network. Each data contains the path for sending packets to each destination in the network and distance/or time to transmit on that path (we call this as "cost"). The measurements in this algorithm are the number of hops, latency, the number of outgoing packets, etc.
The Bellman–Ford algorithm is an algorithm that computes shortest paths from a single source vertex to all of the other vertices in a weighted digraph. It is slower than Dijkstra's algorithm for the same problem, but more versatile, as it is capable of handling graphs in which some of the edge weights are negative numbers. Negative edge weights are found in various applications of graphs, hence the usefulness of this algorithm. If a graph contains a "negative cycle" (i.e. a cycle whose edges sum to a negative value) that is reachable from the source, then there is no cheapest path: any path that has a point on the negative cycle can be made cheaper by one more walk around the negative cycle. In such a case, the Bellman–Ford algorithm can detect negative cycles and report their existence.

 

Source code:
package bellmanford;

import java.util.Scanner;

public class BellmanFord {

    public static void main(String[] args) {
        int MAX_VALUE = 999;
        Scanner scan = new Scanner(System.in);
        System.out.println("Enter the number of vertices");
        int num_ver = scan.nextInt();
        int A[][] = new int[num_ver + 1][num_ver + 1];
        System.out.println("Enter the cost adjacency matrix, 0 for self loop, 999 for no edge");
        for (int sn = 1; sn <= num_ver; sn++) {
            for (int dn = 1; dn <= num_ver; dn++) {
                A[sn][dn] = scan.nextInt();
            }
        }
        System.out.println("Enter the source vertex");
        int source = scan.nextInt();
      
       /*Create Distance Matrix D and initialize it*/
        int D[] = new int[num_ver + 1];
        for (int node = 1; node <= num_ver; node++) {
            D[node] = MAX_VALUE;
        }
        D[source] = 0;
               /*Relaxation of edges n-1 times*/
        for (int i = 1; i < num_ver; i++) {
            for (int sn = 1; sn <= num_ver; sn++) {
                for (int dn = 1; dn <= num_ver; dn++) {
                    if (D[dn] > D[sn] + A[sn][dn]) {
                        D[dn] = D[sn] + A[sn][dn];
                    }
                }
            }
        }
               /*To check for negative weight cycle*/
        for (int sn = 1; sn <= num_ver; sn++) {
            for (int dn = 1; dn <= num_ver; dn++) {

                if (D[dn] > D[sn] + A[sn][dn]) {
                    System.out.println("The Graph contains negative edge cycle");
                    return;
                }

            }
        }
        for (int vertex = 1; vertex <= num_ver; vertex++) {
            System.out.println("distance of source " + source + " to " + vertex + " is " + D[vertex]);
        }
    }

}




/*
Run1:
 Enter the number of vertices
 4
 Enter the cost adjacency matrix, 0 for self loop, 999 for no edge
 0            4             999        5
 999       0             999        999
 999       -10         0             999
 999       999        3             0
 Enter the source vertex
 1
 distance of source 1 to 1 is 0
 distance of source 1 to 2 is -2
 distance of source 1 to 3 is 8
 distance of source 1 to 4 is 5

 Run 2:
 Enter the number of vertices
 4
 Enter the cost adjacency matrix, 0 for self loop, 999 for no edge
 0            4       999              5
 999       0             999        5
 999       -10         0             999
 999       999        3             0
 Enter the source vertex
 1
 The Graph contains negative edge cycle
 */