Java Code Examples: Network Algorithms & Protocols

Bellman-Ford Algorithm in Java

This code implements the Bellman-Ford algorithm, which is used to find the shortest paths from a single source vertex to all other vertices in a weighted directed graph. It can handle graphs with negative edge weights.

import java.util.Scanner;

public class BellmanFord {
    private int distances[];
    private int numberofvertices;
    public static final int MAX_VALUE = 999;

    public BellmanFord(int numberofvertices) {
        this.numberofvertices = numberofvertices;
        distances = new int[numberofvertices + 1];
    }

    public void BellmanFordEvaluation(int source, int destination, int adjacencymatrix[][]) {
        for (int node = 1; node <= numberofvertices; node++) {
            distances[node] = MAX_VALUE;
        }
        distances[source] = 0;
        for (int node = 1; node <= numberofvertices - 1; node++) {
            for (int sourcenode = 1; sourcenode <= numberofvertices; sourcenode++) {
                for (int destinationnode = 1; destinationnode <= numberofvertices; destinationnode++) {
                    if (adjacencymatrix[sourcenode][destinationnode] != MAX_VALUE) {
                        if (distances[destinationnode] > distances[sourcenode] + adjacencymatrix[sourcenode][destinationnode]) {
                            distances[destinationnode] = distances[sourcenode] + adjacencymatrix[sourcenode][destinationnode];
                        }
                    }
                }
            }
        }
        for (int sourcenode = 1; sourcenode <= numberofvertices; sourcenode++) {
            for (int destinationnode = 1; destinationnode <= numberofvertices; destinationnode++) {
                if (adjacencymatrix[sourcenode][destinationnode] != MAX_VALUE) {
                    if (distances[destinationnode] > distances[sourcenode] + adjacencymatrix[sourcenode][destinationnode]) {
                        System.out.println("The Graph contains a negative edge cycle");
                        return;
                    }
                }
            }
        }
        for (int vertex = 1; vertex <= numberofvertices; vertex++) {
            if (vertex == destination) {
                System.out.println("Distance of source " + source + " to " + vertex + " is " + distances[vertex]);
            }
        }
    }

    public static void main(String... arg) {
        int numberofvertices = 0;
        int source, destination;
        Scanner scanner = new Scanner(System.in);
        System.out.println("Enter the number of vertices:");
        numberofvertices = scanner.nextInt();
        int adjacencymatrix[][] = new int[numberofvertices + 1][numberofvertices + 1];
        System.out.println("Enter the adjacency matrix:");
        for (int sourcenode = 1; sourcenode <= numberofvertices; sourcenode++) {
            for (int destinationnode = 1; destinationnode <= numberofvertices; destinationnode++) {
                adjacencymatrix[sourcenode][destinationnode] = scanner.nextInt();
                if (sourcenode == destinationnode) {
                    adjacencymatrix[sourcenode][destinationnode] = 0;
                    continue;
                }
                if (adjacencymatrix[sourcenode][destinationnode] == 0) {
                    adjacencymatrix[sourcenode][destinationnode] = MAX_VALUE;
                }
            }
        }
        System.out.println("Enter the source vertex:");
        source = scanner.nextInt();
        System.out.println("Enter the destination vertex:");
        destination = scanner.nextInt();
        BellmanFord bellmanford = new BellmanFord(numberofvertices);
        bellmanford.BellmanFordEvaluation(source, destination, adjacencymatrix);
        scanner.close();
    }
}

Datagram Socket Example in Java

This code demonstrates a simple client-server communication using Datagram Sockets in Java. Datagram Sockets are connectionless, meaning that each packet is sent independently.

import java.net.*;

class DatagramExample {
    public static int serverPort = 666;
    public static int clientPort = 999;
    public static int bufferSize = 1024;
    public static DatagramSocket ds;
    public static byte[] buffer = new byte[bufferSize];

    public static void runServer() throws Exception {
        int pos = 0;
        System.out.println("Server is running...");
        while (true) {
            int c = System.in.read();
            switch (c) {
                case -1:
                    System.out.println("Server Quits.");
                    return;
                case '\r':
                    break;
                case '\n':
                    ds.send(new DatagramPacket(buffer, pos, InetAddress.getLocalHost(), clientPort));
                    pos = 0;
                    break;
                default:
                    if (pos < buffer.length) {
                        buffer[pos++] = (byte) c;
                    } else {
                        System.out.println("Buffer overflow. Ignoring extra input.");
                    }
            }
        }
    }

    public static void runClient() throws Exception {
        System.out.println("Client is running...");
        while (true) {
            DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
            ds.receive(packet);
            System.out.println("Received: " + new String(packet.getData(), 0, packet.getLength()));
        }
    }

    public static void main(String[] args) throws Exception {
        if (args.length == 1 && args[0].equals("server")) {
            ds = new DatagramSocket(serverPort);
            runServer();
        } else {
            ds = new DatagramSocket(clientPort);
            runClient();
        }
    }
}

Leaky Bucket Algorithm in Java

This code implements the Leaky Bucket algorithm, a traffic shaping mechanism used in networking to control the rate of data transmission.

import java.util.Scanner;

public class LeakyBucket {
    public static void main(String[] args) {
        Scanner my = new Scanner(System.in);
        System.out.print("\nEnter the bucket size: ");
        int bucket_size = my.nextInt();
        System.out.print("\nEnter the number of groups: ");
        int no_groups = my.nextInt();
        int no_packets[] = new int[no_groups];
        int in_bw[] = new int[no_groups];
        int reqd_bw = 0, tot_packets = 0;
        for (int i = 0; i < no_groups; i++) {
            System.out.print("\nEnter the number of packets for group " + (i + 1) + ": ");
            no_packets[i] = my.nextInt();
            System.out.print("\nEnter the input bandwidth for group " + (i + 1) + ": ");
            in_bw[i] = my.nextInt();
            if ((tot_packets + no_packets[i]) <= bucket_size) {
                tot_packets += no_packets[i];
            } else {
                while ((tot_packets + no_packets[i]) > bucket_size) {
                    System.out.println("Bucket Overflow");
                    System.out.println("Enter a value less than " + (bucket_size - tot_packets));
                    no_packets[i] = my.nextInt();
                }
                tot_packets += no_packets[i];
            }
            reqd_bw += (no_packets[i] * in_bw[i]);
        }
        System.out.println("\nThe total required bandwidth is: " + reqd_bw);
        System.out.print("Enter the output bandwidth: ");
        int out_bw = my.nextInt();
        int temp_bw = reqd_bw;
        int rem_pkts = tot_packets;
        while ((temp_bw > 0) && (rem_pkts > 0)) {
            if (temp_bw >= out_bw) {
                System.out.println("\nData Sent. " + (--rem_pkts) + " packet(s) remaining.");
                temp_bw -= out_bw;
                System.out.println("Remaining Bandwidth: " + temp_bw);
            } else {
                System.out.println(rem_pkts + " packet(s) discarded due to insufficient bandwidth.");
                break;
            }
        }
        if (temp_bw == 0) {
            System.out.println("\nAll data has been sent successfully!");
        } else if (rem_pkts == 0) {
            System.out.println("\nNo more packets left to send.");
        }
        my.close();
    }
}

RSA Algorithm in Java

This code implements the RSA algorithm, a widely used public-key cryptosystem for secure data transmission.

import java.io.DataInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Random;

public class Encrypt {
    private BigInteger p;
    private BigInteger q;
    private BigInteger N;
    private BigInteger phi;
    private BigInteger e;
    private BigInteger d;
    private int bitlength = 1024;
    private Random r;

    public Encrypt() {
        r = new Random();
        p = BigInteger.probablePrime(bitlength, r);
        q = BigInteger.probablePrime(bitlength, r);
        N = p.multiply(q);
        phi = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
        e = BigInteger.probablePrime(bitlength / 2, r);
        while (phi.gcd(e).compareTo(BigInteger.ONE) > 0 && e.compareTo(phi) < 0) {
            e = e.add(BigInteger.ONE);
        }
        d = e.modInverse(phi); 
    }

    public Encrypt(BigInteger e, BigInteger d, BigInteger N) {
        this.e = e;
        this.d = d;
        this.N = N;
    }

    public static void main(String[] args) throws IOException {
        Encrypt rsa = new Encrypt();
        DataInputStream in = new DataInputStream(System.in);
        System.out.println("Enter the plain text:");
        String testString = in.readLine();
        System.out.println("Encrypting String: " + testString);
        System.out.println("String in Bytes: " + bytesToString(testString.getBytes()));
        byte[] encrypted = rsa.encrypt(testString.getBytes());
        System.out.println("Encrypted Bytes: " + bytesToString(encrypted));
        byte[] decrypted = rsa.decrypt(encrypted);
        System.out.println("Decrypting Bytes: " + bytesToString(decrypted));
        System.out.println("Decrypted String: " + new String(decrypted));
    }

    private static String bytesToString(byte[] encrypted) {
        StringBuilder sb = new StringBuilder();
        for (byte b : encrypted) {
            sb.append(Byte.toString(b)).append(" ");
        }
        return sb.toString();
    }

    public byte[] encrypt(byte[] message) {
        return (new BigInteger(message)).modPow(e, N).toByteArray();
    }

    public byte[] decrypt(byte[] message) {
        return (new BigInteger(message)).modPow(d, N).toByteArray();
    }
}

Sliding Window Protocol in Java

This code simulates the Sliding Window Protocol, a flow control protocol used in computer networks to improve the efficiency of data transmission.

public class SlidingWindowProtocol {
    private final int windowSize;
    private int sendBase;
    private int nextSeqNum;

    public SlidingWindowProtocol(int windowSize) {
        this.windowSize = windowSize;
        this.sendBase = 0;
        this.nextSeqNum = 0;
    }

    public void sendData(char[] data) {
        while (nextSeqNum < sendBase + windowSize && nextSeqNum < data.length) {
            Packet packet = createPacket(data[nextSeqNum]);
            simulateSendPacket(packet);
            nextSeqNum++;
        }
    }

    public void receiveAck(int ackNum) {
        sendBase = ackNum + 1;
    }

    private Packet createPacket(char data) {
        return new Packet(nextSeqNum, data);
    }

    private void simulateSendPacket(Packet packet) {
        System.out.println("Sending packet: " + packet);
    }

    public void simulateAckPacket(int ackNum) {
        System.out.println("Received ACK for packet: " + ackNum);
        receiveAck(ackNum);
    }

    private static class Packet {
        private final int seqNum;
        private final char data;

        public Packet(int seqNum, char data) {
            this.seqNum = seqNum;
            this.data = data;
        }

        public String toString() {
            return "Packet{" +
                    "seqNum=" + seqNum +
                    ", data=" + data +
                    '}';
        }
    }

    public static void main(String[] args) {
        char[] data = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
        SlidingWindowProtocol swp = new SlidingWindowProtocol(4);
        swp.sendData(data);
        swp.simulateAckPacket(0);
        swp.simulateAckPacket(1);
        swp.simulateAckPacket(2);
        swp.simulateAckPacket(3);
    }
}

TCP/IP File Transfer in Java

This code demonstrates a simple file transfer application using TCP/IP Sockets in Java. TCP/IP provides a reliable, ordered, and error-checked delivery of a stream of data between applications running on hosts communicating over an IP network.

Client

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

class Client {
    public static void main(String args[]) throws Exception {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter server address:");
        String address = sc.nextLine();
        Socket s = new Socket(address, 5000);
        DataInputStream din = new DataInputStream(s.getInputStream());
        DataOutputStream dout = new DataOutputStream(s.getOutputStream());
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Send 'start' to initiate file transfer:");
        String str = br.readLine();
        dout.writeUTF(str);
        dout.flush();
        if (!str.equalsIgnoreCase("start")) {
            System.out.println("Invalid command. Exiting...");
            s.close();
            return;
        }
        String filename = din.readUTF();
        System.out.println("Receiving file: " + filename);
        filename = "client_" + filename;
        System.out.println("Saving as file: " + filename);
        long fileSize = Long.parseLong(din.readUTF());
        System.out.println("File size: " + (fileSize / 1024) + " KB");
        byte[] buffer = new byte[1024];
        FileOutputStream fos = new FileOutputStream(new File(filename));
        long totalBytesRead = 0;
        System.out.println("Receiving file...");
        while (totalBytesRead < fileSize) {
            int bytesRead = din.read(buffer, 0, buffer.length);
            fos.write(buffer, 0, bytesRead);
            totalBytesRead += bytesRead;
        }
        System.out.println("File transfer completed. File saved as: " + filename);
        fos.close();
        din.close();
        dout.close();
        s.close();
    }
}

Server

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

class Server {
    public static void main(String args[]) throws Exception {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter filename to send:");
        String filename = sc.nextLine();
        File file = new File(filename);
        if (!file.exists()) {
            System.out.println("File does not exist. Exiting...");
            return;
        }
        while (true) {
            ServerSocket ss = new ServerSocket(5000);
            System.out.println("Waiting for client request...");
            Socket s = ss.accept();
            System.out.println("Connected with " + s.getInetAddress());
            DataInputStream din = new DataInputStream(s.getInputStream());
            DataOutputStream dout = new DataOutputStream(s.getOutputStream());
            try {
                String command = din.readUTF();
                System.out.println("Client command received: " + command);
                if (!command.equalsIgnoreCase("start")) {
                    System.out.println("Invalid command. Closing connection...");
                    s.close();
                    ss.close();
                    continue;
                }
                System.out.println("Sending file: " + filename);
                dout.writeUTF(file.getName());
                dout.flush();
                long fileSize = file.length();
                dout.writeUTF(Long.toString(fileSize));
                dout.flush();
                FileInputStream fis = new FileInputStream(file);
                byte[] buffer = new byte[1024];
                int bytesRead;
                System.out.println("File size: " + fileSize + " bytes");
                while ((bytesRead = fis.read(buffer)) != -1) {
                    dout.write(buffer, 0, bytesRead);
                    dout.flush();
                }
                fis.close();
                System.out.println("File transfer completed.");
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("Error occurred during file transfer.");
            } finally {
                din.close();
                dout.close();
                s.close();
                ss.close();
            }
        }
    }
}