Docker to Docker Networking Between TCP Client and Server
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
Java
x
123
1
import java.net.*;
2
import java.io.*;
3
import java.security.SecureRandom;
4
import java.nio.charset.Charset;
5
6
public class TCPClient
7
{
8
// initialize socket and input output streams
9
private Socket socket = null;
10
private DataInputStream input = null;
11
private DataOutputStream out = null;
12
13
private static final String CHAR_LOWER = "abcdefghijklmnopqrstuvwxyz";
14
private static final String CHAR_UPPER = CHAR_LOWER.toUpperCase();
15
private static final String NUMBER = "0123456789";
16
17
private static final String DATA_FOR_RANDOM_STRING = CHAR_LOWER + CHAR_UPPER + NUMBER;
18
private static SecureRandom random = new SecureRandom();
19
20
// constructor to put ip address and port
21
public TCPClient(String address, int port)
22
{
23
24
25
26
// establish a connection
27
try
28
{
29
socket = new Socket(address, port);
30
System.out.println("Connected");
31
32
33
34
}
35
catch(UnknownHostException u)
36
{
37
System.out.println(u);
38
}
39
catch(IOException i)
40
{
41
System.out.println(i);
42
}
43
44
// string to read message from input
45
String line = "";
46
int linecount = 0;
47
48
// keep reading until "Over" is input
49
while (linecount++ != 300)
50
{
51
52
53
try{
54
String name = generateRandomString(8);
55
56
InputStream is = new ByteArrayInputStream(name.getBytes(Charset.forName("UTF-8")));
57
// takes input from terminal
58
input = new DataInputStream(is);
59
60
// sends output to the socket
61
out = new DataOutputStream(socket.getOutputStream());
62
}
63
catch(UnknownHostException u)
64
{
65
System.out.println(u);
66
}
67
catch(IOException i)
68
{
69
System.out.println(i);
70
}
71
72
try
73
{
74
line = input.readLine();
75
out.writeUTF(line);
76
}
77
catch(IOException i)
78
{
79
System.out.println(i);
80
}
81
}
82
83
// close the connection
84
try
85
{
86
input.close();
87
out.close();
88
socket.close();
89
}
90
catch(IOException i)
91
{
92
System.out.println(i);
93
}
94
}
95
96
public static String generateRandomString(int length) {
97
if (length < 1) throw new IllegalArgumentException();
98
99
StringBuilder sb = new StringBuilder(length);
100
for (int i = 0; i < length; i++) {
101
102
// 0-62 (exclusive), random returns 0-61
103
int rndCharAt = random.nextInt(DATA_FOR_RANDOM_STRING.length());
104
char rndChar = DATA_FOR_RANDOM_STRING.charAt(rndCharAt);
105
106
// debug
107
System.out.format("%d\t:\t%c%n", rndCharAt, rndChar);
108
109
sb.append(rndChar);
110
111
}
112
113
return sb.toString();
114
115
}
116
public static void main(String args[])
117
{
118
TCPClient client = new TCPClient("server", 5678);
119
}
120
}
121
Create a manifest file for the TCPClient as is shown below:
Java
xxxxxxxxxx
1
1
Manifest-Version: 1.0
2
Created-By: Me
3
Main-Class: TCPClient
Create a Dockerfile for TCPClient as below:
Dockerfile
xxxxxxxxxx
1
1
FROM java:8
2
WORKDIR /
3
ADD TCPClient.jar TCPClient.jar
4
EXPOSE 5678
5
CMD java -jar TCPClient.jar
Create a TCPServer.java as per the code provided below:
Java
xxxxxxxxxx
1
74
1
import java.net.*;
2
import java.io.*;
3
4
public class TCPServer
5
{
6
//initialize socket and input stream
7
private Socket socket = null;
8
private ServerSocket server = null;
9
private DataInputStream in = null;
10
private File file;
11
private FileWriter fileWriter;
12
13
// constructor with port
14
public TCPServer(int port)
15
{
16
// starts server and waits for a connection
17
try
18
{
19
server = new ServerSocket(port);
20
System.out.println("Server started");
21
22
System.out.println("Waiting for a client ...");
23
24
socket = server.accept();
25
System.out.println("Client accepted");
26
27
// takes input from the client socket
28
in = new DataInputStream(
29
new BufferedInputStream(socket.getInputStream()));
30
31
String line = "";
32
int linecount = 0;
33
34
file = new File("outfile.txt");
35
fileWriter = new FileWriter(file);
36
37
38
// reads message from client until "Over" is sent
39
while (linecount++ != 300)
40
{
41
try
42
{
43
line = in.readUTF();
44
System.out.println(line);
45
fileWriter.write(line);
46
47
48
49
}
50
catch(IOException i)
51
{
52
System.out.println(i);
53
}
54
}
55
System.out.println("Closing connection");
56
fileWriter.flush();
57
fileWriter.close();
58
// close connection
59
socket.close();
60
in.close();
61
}
62
catch(IOException i)
63
{
64
System.out.println(i);
65
}
66
}
67
68
public static void main(String args[])
69
{
70
TCPServer server = new TCPServer(5678);
71
}
72
}
Create a manifest file for TCPServer as below:
Shell
xxxxxxxxxx
1
1
Manifest-Version: 1.0
2
Created-By: Me
3
Main-Class: TCPServer
Create a Dockerfile for TCPServer as below
Shell
xxxxxxxxxx
1
1
FROM java:8
2
WORKDIR /
3
ADD TCPServer.jar TCPServer.jar
4
EXPOSE 5678
5
CMD java -jar TCPServer.jar
The directory structure should be as displayed as shown below:
Run the following commands at the unix prompt:
Shell
xxxxxxxxxx
1
41
1
javac TCPServer.java
2
3
javac TCPClient.java
4
5
6
7
jar cfm TCPServer.jar manifest.txt TCPServer.class
8
9
jar cfm TCPClient.jar manifest.txt TCPClient.class
10
11
12
13
docker build -t tcpserver .
14
15
docker build -t tcpclient .
16
17
18
19
docker images (to list the docker images)
20
21
docker tag 00c5f2d27133 docker.io/<your account name>/<repo name>:tcpserver
22
23
docker push docker.io/<your account name>/<repo name>:tcpserver
24
25
26
27
docker images (to list the docker images)
28
29
docker tag 00c5f2d27133 docker.io/<your account name>/<repo name>:tcpclient
30
31
docker push docker.io/<your account name>/<repo name>:tcpclient
32
33
34
35
docker pull docker.io/<your account name>/<repo name>:tcpserver
36
37
docker pull docker.io/<your account name>/<repo name>:tcpclient
38
39
docker run <your account name>/<repo name>:tcpserver
40
41
docker run <your account name>/<repo name>:tcpclient
Create the network:
Shell
xxxxxxxxxx
1
1
sudo docker network create client_server_network
Run the server:
Shell
xxxxxxxxxx
1
1
docker run --network-alias server --network client_server_network -it <your account name>/<repo name>:tcpserver
Run the client:
Shell
xxxxxxxxxx
1
1
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: