Docker to Docker Networking Between TCP Client and Server

telephone

Take a look at how two containers communicate


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

Presented in this article are:

  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 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:

Directory structure

   
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:

Client output


And the server output should be as shown below:

Server output



 

 

 

 

Top