Skip to content

Instantly share code, notes, and snippets.

@Lakhan-Nad
Created November 3, 2020 15:55
Show Gist options
  • Save Lakhan-Nad/c7dc0977defcd256a459823ab9600b2a to your computer and use it in GitHub Desktop.
Save Lakhan-Nad/c7dc0977defcd256a459823ab9600b2a to your computer and use it in GitHub Desktop.
Generic Client-Server program boilerplate code. Easily customizable as per your requirements
package client;
import java.io.Console;
import java.util.Scanner;
public final class Client {
private static Session session;
private static Scanner sc;
private Client() {
// empty constructor
}
/**
* To wait for an confirmation from the command line
* @param message The format of message to print
* @param args Args represents the data to print
*/
public static void waitForEnter(String message, Object... args) {
Console c = System.console();
if (c != null) {
// printf-like arguments
if (message != null)
c.format(message, args);
c.format(" --Press ENTER to proceed.");
c.readLine();
}
}
/**
* The starting point of the client side program
* @param args an array of command line inputs
*/
public static void main(String[] args) {
sc = new Scanner(System.in);
String message = "1. For new Connection type: connect <hostname> <port>\n2. newKeys to calculate new permanent Keys\n3. Anything else to exit application\n";
newSession();
}
/**
* A function to maintain a new client session
* It creates a new session and does all key exchange part
* The session takes a argument of ip address/hostname and port
*/
private static void newSession(String host, int port) {
waitForEnter("Send Connection Request To Server?");
session = new Session("localhost", 9001);
if(session.connect(){
/**
* Write your application specific logic
* Create the functions for Session class specific
* to your requirements
*/
}
session.close();
}
}
package server;
import java.io.*;
import java.math.BigInteger;
import java.net.Socket;
import java.util.Random;
public final class ClientThread extends Thread {
private final Socket socket;
private long maxWait = 2 * 60 * 1000; // 2 minutes
DataInputStream in = null;
DataOutputStream out = null;
ClientThread(Socket socket) {
this.socket = socket;
}
/**
* To see if the I/O Channels are available for a given client
* and if yes open them
*/
private void establishIO() {
if (in != null) {
try {
in.close();
} catch (Exception e) {
System.out.println("Unable to close Input Stream");
}
}
if (out != null) {
try {
out.close();
} catch (Exception e) {
System.out.println("Unable to close Output Stream");
}
}
try {
if (!socket.isInputShutdown())
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
if (!socket.isInputShutdown())
out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
} catch (Exception e) {
System.out.println("Unable to open communication streams");
return;
}
if (in == null || out == null) {
System.out.println("Communication Channels Unavailable");
}
}
/**
* To run this particular client thread
* Entry point of client communication
*/
public void run() {
establishIO();
/**
* Application Specific Logic
*/
close();
}
/**
* A utility to close the connection and
* release the resources
*/
private void close() {
try {
if (socket != null)
socket.close();
if (out != null)
out.close();
if (in != null)
in.close();
} catch (Exception e) {
System.out.println("Unable to Close the Connection");
}
/* Documentation */
System.out.println("Connection Closed with " + socket.getInetAddress());
}
}
package server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public final class Server {
private static ServerSocket server;
private Server() {
// Empty Constructor
}
/**
* A function to check if the required command line arguments were passed or not
* It also creates the socket for listening connections.
* @param args command line arguments
*/
private static void handleArgs(String[] args) {
int port;
try {
port = Integer.parseInt(args[0]);
} catch (NumberFormatException e) {
System.out.println("Port is not a valid number");
return;
}
// try creating a ServerSocket
try {
server = new ServerSocket(port);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
/**
* A function that handles a particular client
* This function opens a client and returns a thread
* @param socket the socket representing a client
* @return thread created to handle client
*/
private static Thread handleConnection(Socket socket) {
System.out.println("Connection request from: " + socket.getInetAddress());
Thread th = new ClientThread(socket);
try {
th.start();
} catch (Exception e) {
return null;
}
return th;
}
/**
* Main function to start a client running
* @param args command line arguments
*/
public static void main(String[] args) {
handleArgs(args);
if (server == null) {
System.out.println("Unable to initiate a server");
System.exit(1);
}
ArrayList<Thread> clientThreads = new ArrayList<>();
/* Documentation */
System.out.println("Server Started At: " + server.getLocalPort());
int connections = 2;
/**
* The main loop to listen for connections
* we can set a limit to no of connections we will
* wait for or set it upto resource allows
*
* The code here take a client connection request and
* open a new thread to communicate with client
*/
while (connections > 0) {
Socket socket = null;
try {
socket = server.accept();
} catch (Exception e) {
System.out.println("Unable to accept request");
}
if (socket != null) {
Thread newClient = handleConnection(socket);
if(newClient != null)
clientThreads.add(newClient);
else
System.out.println("The client connection refused unable to allocate a new thread");
connections--;
} else {
System.out.println("Connection Error");
}
}
/**
* This code waits for all the client thread to close
* before exiting the server program
*/
for(int i = 0; i < clientThreads.size(); i++){
try {
clientThreads.get(i).join();
}catch (InterruptedException e){
System.out.println("A client thread was interrupted");
}
}
// Close the server/listening socket
if (server != null) {
try {
server.close();
} catch (IOException e) {
System.out.println(e.getMessage());
System.exit(0);
}
}
}
}
package client;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
class Session {
private Socket socket;
private DataOutputStream out;
private DataInputStream in;
private final String ip;
private final int port;
/**
* @param ip the ip address or host to connect
* @param port the port number to identify the process
*/
public Session(String ip, int port) {
this.ip = ip;
this.port = port;
}
/**
* Function called to connect to Server
* @return if connection was established or not
*/
public boolean connect() {
if (socket != null) {
try {
socket.close();
} catch (Exception e) {
System.out.println("Client busy couldn't establish new connection");
}
}
/* Documentation */
System.out.println("Sending Connection Request To Server");
try {
socket = new Socket(ip, port);
} catch (Exception e) {
System.out.println("Invalid Host or Port provided or no listener");
return false;
}
return establishIO();
}
/**
* To check if IO from server is established or not
* IO is the input stream and output stream for the
* connection from client side.
* @return boolean for same
*/
private boolean establishIO() {
if (socket == null) {
System.out.println("Establish a Connection Before");
return false;
}
if (in != null) {
try {
in.close();
} catch (Exception e) {
System.out.println("Input Channel Error");
return false;
}
}
if (out != null) {
try {
out.close();
} catch (Exception e) {
System.out.println("Output Channel Error");
return false;
}
}
try {
out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
} catch (Exception e) {
System.out.println("Unable to open a I/O Channel");
return false;
}
return true;
}
/**
* Close the connection
*/
public void close() {
try {
if (socket != null)
socket.close();
if (in != null)
in.close();
if (out != null)
out.close();
} catch (Exception e) {
System.out.println("Unable to close Resources");
}
/* Documentation */
System.out.println("Connection with Server Closed");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment