Docker to Docker networking between TCP Client and Server

A TCP based client and server is a frequently needed setup in IoT based applications.

Presented in this article is :

  1. A method to create a java based client and server to send and receive binary data
  2. The client and server each run inside a docker container and communicate through docker networking.

Create a TCPClient.java as per the code provided below



import java.net.*; 
import java.io.*; 
import java.security.SecureRandom;
import java.nio.charset.Charset;

public class TCPClient 
{ 
	// initialize socket and input output streams 
	private Socket socket		 = null; 
	private DataInputStream input = null; 
	private DataOutputStream out	 = null; 
	
	private static final String CHAR_LOWER = "abcdefghijklmnopqrstuvwxyz";
	private static 	final String CHAR_UPPER = CHAR_LOWER.toUpperCase();
	private static 	final String NUMBER = "0123456789";

	private static final String DATA_FOR_RANDOM_STRING = CHAR_LOWER + CHAR_UPPER + NUMBER;
	private static SecureRandom random = new SecureRandom();

	// constructor to put ip address and port 
	public TCPClient(String address, int port) 
	{ 
	

	
		// establish a connection 
		try
		{ 
			socket = new Socket(address, port); 
			System.out.println("Connected"); 

		

		} 
		catch(UnknownHostException u) 
		{ 
			System.out.println(u); 
		} 
		catch(IOException i) 
		{ 
			System.out.println(i); 
		} 

		// string to read message from input 
		String line = ""; 
		int linecount = 0;

		// keep reading until "Over" is input 
		while (linecount++ != 300) 
		{ 
	
	
			try{
				String name = generateRandomString(8);

				InputStream is = new ByteArrayInputStream(name.getBytes(Charset.forName("UTF-8")));
				// takes input from terminal 
				input = new DataInputStream(is); 

				// sends output to the socket 
				out = new DataOutputStream(socket.getOutputStream()); 
			} 
			catch(UnknownHostException u) 
			{ 
				System.out.println(u); 
			} 
			catch(IOException i) 
			{ 
				System.out.println(i); 
			} 				
			
			try
			{ 
				line = input.readLine(); 
				out.writeUTF(line); 
			} 
			catch(IOException i) 
			{ 
				System.out.println(i); 
			} 
		} 

		// close the connection 
		try
		{ 
			input.close(); 
			out.close(); 
			socket.close(); 
		} 
		catch(IOException i) 
		{ 
			System.out.println(i); 
		} 
	} 

    public static String generateRandomString(int length) {
        if (length < 1) throw new IllegalArgumentException();

        StringBuilder sb = new StringBuilder(length);
        for (int i = 0; i < length; i++) {

			// 0-62 (exclusive), random returns 0-61
            int rndCharAt = random.nextInt(DATA_FOR_RANDOM_STRING.length());
            char rndChar = DATA_FOR_RANDOM_STRING.charAt(rndCharAt);

            // debug
            System.out.format("%d\t:\t%c%n", rndCharAt, rndChar);

            sb.append(rndChar);

        }

        return sb.toString();

    }
	public static void main(String args[]) 
	{ 
		TCPClient client = new TCPClient("server", 5678); 
	} 
} 

Create a manifest file for TCPClient as below

Manifest-Version: 1.0
Created-By: Me
Main-Class: TCPClient

Create a Dockerfile for TCPClient as below

FROM java:8
WORKDIR /
ADD TCPClient.jar TCPClient.jar
EXPOSE 5678
CMD java -jar TCPClient.jar

Create a TCPServer.java as per the code provided below


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

public class TCPServer 
{ 
	//initialize socket and input stream 
	private Socket		 socket = null; 
	private ServerSocket server = null; 
	private DataInputStream in	 = null; 
	private File file;
	private FileWriter fileWriter;

	// constructor with port 
	public TCPServer(int port) 
	{ 
		// starts server and waits for a connection 
		try
		{ 
			server = new ServerSocket(port); 
			System.out.println("Server started"); 

			System.out.println("Waiting for a client ..."); 

			socket = server.accept(); 
			System.out.println("Client accepted"); 

			// takes input from the client socket 
			in = new DataInputStream( 
				new BufferedInputStream(socket.getInputStream())); 

			String line = ""; 
			int linecount = 0;
			
			file = new File("outfile.txt");
			fileWriter = new FileWriter(file);


			// reads message from client until "Over" is sent 
			while (linecount++ != 300) 
			{ 
				try
				{ 
					line = in.readUTF(); 
					System.out.println(line); 
					fileWriter.write(line);



				} 
				catch(IOException i) 
				{ 
					System.out.println(i); 
				} 
			} 
			System.out.println("Closing connection"); 
			fileWriter.flush();
			fileWriter.close();
			// close connection 
			socket.close(); 
			in.close(); 
		} 
		catch(IOException i) 
		{ 
			System.out.println(i); 
		} 
	} 

	public static void main(String args[]) 
	{ 
		TCPServer server = new TCPServer(5678); 
	} 
} 

Create a manifest file for TCPServer as below

Manifest-Version: 1.0
Created-By: Me
Main-Class: TCPServer

Create a Dockerfile for TCPServer as below

FROM java:8
WORKDIR /
ADD TCPServer.jar TCPServer.jar
EXPOSE 5678
CMD java -jar TCPServer.jar

The directory structure should be as displayed below

Run the following commands at the unix prompt :

javac TCPServer.java

javac TCPClient.java

 

jar cfm TCPServer.jar manifest.txt TCPServer.class

jar cfm TCPClient.jar manifest.txt TCPClient.class

 

docker build -t tcpserver .

docker build -t tcpclient .

 

docker images (to list the docker images)

docker tag 00c5f2d27133 docker.io/<your account name>/<repo name>:tcpserver

docker push docker.io/<your account name>/<repo name>:tcpserver

 

docker images (to list the docker images)

docker tag 00c5f2d27133 docker.io/<your account name>/<repo name>:tcpclient

docker push docker.io/<your account name>/<repo name>:tcpclient

 

docker pull docker.io/<your account name>/<repo name>:tcpserver

docker pull docker.io/<your account name>/<repo name>:tcpclient

docker run <your account name>/<repo name>:tcpserver

docker run <your account name>/<repo name>:tcpclient

Create the network – 

sudo docker network create client_server_network

Run the server –

docker run --network-alias server --network client_server_network -it <your account name>/<repo name>:tcpserver

Run the client –

docker run --network client_server_network -it <your account name>/<repo name>:tcpclient

You should see the client output as below

And the server output should be as shown below

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: