Docker to Docker Networking Between TCP Client and Server
This article presents a step-by-step instructions on how to create a TCP client and server for IoT applications using Docker containers and networking.
Join the DZone community and get the full member experience.
Join For Free
A TCP-based client and server are a frequently needed setup in IoT-based applications.
Presented in this article are:
- 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 communicating through Docker networking.
You may also enjoy: Understanding 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 the TCPClient as is shown below:
xxxxxxxxxx
Manifest-Version: 1.0
Created-By: Me
Main-Class: TCPClient
Create a Dockerfile for TCPClient as below:
xxxxxxxxxx
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:
xxxxxxxxxx
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:
xxxxxxxxxx
Manifest-Version: 1.0
Created-By: Me
Main-Class: TCPServer
Create a Dockerfile for TCPServer as below
xxxxxxxxxx
FROM java:8
WORKDIR /
ADD TCPServer.jar TCPServer.jar
EXPOSE 5678
CMD java -jar TCPServer.jar
The directory structure should be as displayed as shown below:
Run the following commands at the unix prompt:
xxxxxxxxxx
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:
xxxxxxxxxx
sudo docker network create client_server_network
Run the server:
xxxxxxxxxx
docker run --network-alias server --network client_server_network -it <your account name>/<repo name>:tcpserver
Run the client:
xxxxxxxxxx
docker run --network client_server_network -it <your account name>/<repo name>:tcpclient
You should see the client output as shown below:
And the server output should be as shown below:
Opinions expressed by DZone contributors are their own.
Comments