A TCP based client and server is a frequently needed setup in IoT based applications.
Presented in this article is :
- A method to create a java based client and server to send and receive binary data
- 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
