99import java .net .InetAddress ;
1010import java .net .InetSocketAddress ;
1111import java .net .Socket ;
12- import java .net .SocketException ;
12+ import java .net .UnknownHostException ;
1313import java .util .concurrent .ExecutorService ;
1414import java .util .concurrent .Executors ;
1515import java .util .concurrent .TimeUnit ;
1616
17+ /**
18+ * Represents the clients of Reactor pattern. Multiple clients are run concurrently and send logging
19+ * requests to Reactor.
20+ *
21+ * @author npathai
22+ */
1723public class AppClient {
18- private ExecutorService service = Executors .newFixedThreadPool (3 );
19-
20- public static void main (String [] args ) {
21- new AppClient ().start ();
24+ private ExecutorService service = Executors .newFixedThreadPool (4 );
25+
26+ /**
27+ * App client entry.
28+ * @throws IOException if any I/O error occurs.
29+ */
30+ public static void main (String [] args ) throws IOException {
31+ AppClient appClient = new AppClient ();
32+ appClient .start ();
2233 }
2334
24- public void start () {
25- service .execute (new LoggingClient ("Client 1" , 6666 ));
26- service .execute (new LoggingClient ("Client 2" , 6667 ));
27- service .execute (new UDPLoggingClient (6668 ));
35+ /**
36+ * Starts the logging clients.
37+ * @throws IOException if any I/O error occurs.
38+ */
39+ public void start () throws IOException {
40+ service .execute (new TCPLoggingClient ("Client 1" , 6666 ));
41+ service .execute (new TCPLoggingClient ("Client 2" , 6667 ));
42+ service .execute (new UDPLoggingClient ("Client 3" , 6668 ));
43+ service .execute (new UDPLoggingClient ("Client 4" , 6668 ));
2844 }
29-
45+
46+ /**
47+ * Stops logging clients. This is a blocking call.
48+ */
3049 public void stop () {
3150 service .shutdown ();
3251 if (!service .isTerminated ()) {
@@ -39,96 +58,106 @@ public void stop() {
3958 }
4059 }
4160
42- /*
43- * A logging client that sends logging requests to logging server
61+ private static void artificialDelayOf (long millis ) {
62+ try {
63+ Thread .sleep (millis );
64+ } catch (InterruptedException e ) {
65+ e .printStackTrace ();
66+ }
67+ }
68+
69+ /**
70+ * A logging client that sends requests to Reactor on TCP socket.
4471 */
45- static class LoggingClient implements Runnable {
72+ static class TCPLoggingClient implements Runnable {
4673
4774 private int serverPort ;
4875 private String clientName ;
4976
50- public LoggingClient (String clientName , int serverPort ) {
77+ /**
78+ * Creates a new TCP logging client.
79+ *
80+ * @param clientName the name of the client to be sent in logging requests.
81+ * @param port the port on which client will send logging requests.
82+ */
83+ public TCPLoggingClient (String clientName , int serverPort ) {
5184 this .clientName = clientName ;
5285 this .serverPort = serverPort ;
5386 }
5487
5588 public void run () {
56- Socket socket = null ;
57- try {
58- socket = new Socket (InetAddress .getLocalHost (), serverPort );
89+ try (Socket socket = new Socket (InetAddress .getLocalHost (), serverPort )) {
5990 OutputStream outputStream = socket .getOutputStream ();
6091 PrintWriter writer = new PrintWriter (outputStream );
61- writeLogs (writer , socket .getInputStream ());
92+ sendLogRequests (writer , socket .getInputStream ());
6293 } catch (IOException e ) {
6394 e .printStackTrace ();
6495 throw new RuntimeException (e );
65- } finally {
66- if (socket != null ) {
67- try {
68- socket .close ();
69- } catch (IOException e ) {
70- e .printStackTrace ();
71- }
72- }
7396 }
7497 }
7598
76- private void writeLogs (PrintWriter writer , InputStream inputStream ) throws IOException {
99+ private void sendLogRequests (PrintWriter writer , InputStream inputStream ) throws IOException {
77100 for (int i = 0 ; i < 4 ; i ++) {
78101 writer .println (clientName + " - Log request: " + i );
79- try {
80- Thread .sleep (100 );
81- } catch (InterruptedException e ) {
82- e .printStackTrace ();
83- }
84102 writer .flush ();
103+
85104 byte [] data = new byte [1024 ];
86105 int read = inputStream .read (data , 0 , data .length );
87106 if (read == 0 ) {
88107 System .out .println ("Read zero bytes" );
89108 } else {
90109 System .out .println (new String (data , 0 , read ));
91110 }
111+
112+ artificialDelayOf (100 );
92113 }
93114 }
115+
94116 }
95-
117+
118+ /**
119+ * A logging client that sends requests to Reactor on UDP socket.
120+ */
96121 static class UDPLoggingClient implements Runnable {
97- private int port ;
122+ private String clientName ;
123+ private InetSocketAddress remoteAddress ;
98124
99- public UDPLoggingClient (int port ) {
100- this .port = port ;
125+ /**
126+ * Creates a new UDP logging client.
127+ *
128+ * @param clientName the name of the client to be sent in logging requests.
129+ * @param port the port on which client will send logging requests.
130+ * @throws UnknownHostException if localhost is unknown
131+ */
132+ public UDPLoggingClient (String clientName , int port ) throws UnknownHostException {
133+ this .clientName = clientName ;
134+ this .remoteAddress = new InetSocketAddress (InetAddress .getLocalHost (), port );
101135 }
102-
136+
103137 @ Override
104138 public void run () {
105- DatagramSocket socket = null ;
106- try {
107- socket = new DatagramSocket ();
139+ try (DatagramSocket socket = new DatagramSocket ()) {
108140 for (int i = 0 ; i < 4 ; i ++) {
109- String message = "UDP Client" + " - Log request: " + i ;
110- try {
111- DatagramPacket packet = new DatagramPacket (message .getBytes (), message .getBytes ().length , new InetSocketAddress (InetAddress .getLocalHost (), port ));
112- socket .send (packet );
113-
114- byte [] data = new byte [1024 ];
115- DatagramPacket reply = new DatagramPacket (data , data .length );
116- socket .receive (reply );
117- if (reply .getLength () == 0 ) {
118- System .out .println ("Read zero bytes" );
119- } else {
120- System .out .println (new String (reply .getData (), 0 , reply .getLength ()));
121- }
122- } catch (IOException e ) {
123- e .printStackTrace ();
141+
142+ String message = clientName + " - Log request: " + i ;
143+ DatagramPacket request = new DatagramPacket (message .getBytes (),
144+ message .getBytes ().length , remoteAddress );
145+
146+ socket .send (request );
147+
148+ byte [] data = new byte [1024 ];
149+ DatagramPacket reply = new DatagramPacket (data , data .length );
150+ socket .receive (reply );
151+ if (reply .getLength () == 0 ) {
152+ System .out .println ("Read zero bytes" );
153+ } else {
154+ System .out .println (new String (reply .getData (), 0 , reply .getLength ()));
124155 }
156+
157+ artificialDelayOf (100 );
125158 }
126- } catch (SocketException e1 ) {
159+ } catch (IOException e1 ) {
127160 e1 .printStackTrace ();
128- } finally {
129- if (socket != null ) {
130- socket .close ();
131- }
132161 }
133162 }
134163 }
0 commit comments