Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

For this activity, you will submit two .java files. You will need to run two cla

ID: 3863358 • Letter: F

Question

For this activity, you will submit two .java files. You will need to run two classes simultaneously for this activity. Make sure you have a compiler that is capable of this.

At this point you’ve written programs that allow a Server to start and a Client to connect to it. We’ve looked at situations in which these programs would be effective ways to work with remote machines, but there’s much more that can be done with these kinds of programs.

To really understand the scope of these programs, we’ll have to introduce more users. The biggest reason Server-based programs are so useful are because they are not exclusive to one user. For this program, we’re going to introduce multiple Clients to the same Server.

This program’s Server will start in the same way as the ones you’ve written so far: it opens a ServerSocket and awaits a connection, but this time with two Clients. The Clients that connect will both be running the exact same code from the same class. To be able to tell which Client will receive what data, the Server will need to keep track of them by creating two different Sockets for the Clients to connect to. In a linear fashion, the Server will accept a connection from two different Clients, and then set up an InputStream and an OutputStream for each one. Using the individual streams, you will then send an ID to each client individually. One Client will receive one ID, and the other Client will receive the other. Both Clients will print out the ID they receive.

Note: Both clients must connect to the Server before the IDs are sent. They must both be connected to the Server simultaneously.

To summarize, your program should do the following:

Create a Server class. This class should have two Sockets; one for each Client.

Create a Client class. This class should be run twice to create two Clients.

Have the Server accept connections from each run of the Client class.

Setup an InputStream and an OutputStream for each Client.

Send an ID to each client – these IDs must be unique.

Have the Client print out the ID it received to the console.

Close everything and disconnect both clients.

Explanation / Answer

SimpleTCPServer.java:

package mar8;

import java.io.*;
import java.net.*;


public class SimpleTCPServer {
   public static void main(String[] args) {
       try {
           // Create server socket listening on port 8888
           ServerSocket server = new ServerSocket(8888);
          
           // to keep number of connections
           int i=0;
          
           // we will keep main thread to be actively polling for new connections
           // and in parallel, the new thread will start the work and do the
           // communication
           while (true) {
               System.out.println("Main Thread: Waiting for client to connect...");
               Socket socket = server.accept();
               System.out.println( ++i + " Client connected");
               Thread t = new ListenToClientThread(socket, i);
               t.start();
           }
          
       } catch (IOException ioe) {
           ioe.printStackTrace();
       }
   }

}

// When you call start() on a Thread it calls run()
class ListenToClientThread extends Thread {
   private Socket socket;
   private int clientNo;

   ListenToClientThread(Socket socket, int clientNo) {
       this.socket = socket;
       this.clientNo = clientNo;
   }

   @Override
   public void run() {
       try {
           // Create read/write from socket
           PrintWriter out = new PrintWriter(socket.getOutputStream(),
                   true);
           BufferedReader in = new BufferedReader(new InputStreamReader(
                   socket.getInputStream()));

           // client address
           InetAddress remoteIp = socket.getInetAddress();

           while (true) {
               // Receiving from client
               String msg = in.readLine();
               System.out.println("Client:" + clientNo + " " + remoteIp + ": " + msg);

               if (msg.equals("exit")) {
                   System.out.println("Client:" + clientNo + " Asked to exit. Leaving connection");
                   break;
               }

               // Sending a string prepended with "Server:"
               out.println("Server:" + msg);
               out.flush();
           }
       } catch (IOException e) {
           e.printStackTrace();
       }
   }
}




SimpleTCPClient.java:

package mar8;

import java.net.*;
import java.io.*;


public class SimpleTCPClient {
   public static void main(String[] args) {
       try {
           Socket socket = new Socket("127.0.0.1", 8888);
          
           // Define read/write from socket
           PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
           BufferedReader in = new BufferedReader(new InputStreamReader(
                   socket.getInputStream()));

           String receiveMessage, sendMessage;
           int i=0;
           while (true) {
               sendMessage = "Message " + ++i; // keyboard reading
              
               boolean exit = false;
               if(i==4) {
                   // ask server to break the connection
                   sendMessage = "exit";
                   exit = true;
               }
              
               System.out.println("Sending: " + sendMessage);
              
               out.println(sendMessage); // sending to server
               out.flush(); // flush the data

               if(exit) {
                   System.out.println("Thank-You. Breaking Now.");
                   break;
               }
               if ((receiveMessage = in.readLine()) != null) {
                   System.out.println("Server Sent: " + receiveMessage); // show server's message
               }
              
               // wait for 0.5 sec
               try {
                   Thread.sleep(500);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }

       } catch (IOException ioe) {
           ioe.printStackTrace();
       }
   }
}



Sample Output:

Client1 Output:
Sending: Message 1
Server Sent: Server:Message 1
Sending: Message 2
Server Sent: Server:Message 2
Sending: Message 3
Server Sent: Server:Message 3
Sending: exit
Thank-You. Breaking Now.

Client2 Output:

Sending: Message 1
Server Sent: Server:Message 1
Sending: Message 2
Server Sent: Server:Message 2
Sending: Message 3
Server Sent: Server:Message 3
Sending: exit
Thank-You. Breaking Now.


and so on for other clients.

Server Output:
Main Thread: Waiting for client to connect...
1 Client connected
Main Thread: Waiting for client to connect...
Client:1 /127.0.0.1: Message 1
Client:1 /127.0.0.1: Message 2
Client:1 /127.0.0.1: Message 3
Client:1 /127.0.0.1: exit
Client:1 Asked to exit. Leaving connection
2 Client connected
Main Thread: Waiting for client to connect...
Client:2 /127.0.0.1: Message 1
3 Client connected
Main Thread: Waiting for client to connect...
Client:3 /127.0.0.1: Message 1
4 Client connected
Main Thread: Waiting for client to connect...
Client:4 /127.0.0.1: Message 1
5 Client connected
Main Thread: Waiting for client to connect...
Client:5 /127.0.0.1: Message 1
6 Client connected
Main Thread: Waiting for client to connect...
Client:6 /127.0.0.1: Message 1
7 Client connected
Main Thread: Waiting for client to connect...
Client:7 /127.0.0.1: Message 1
8 Client connected
Main Thread: Waiting for client to connect...
Client:8 /127.0.0.1: Message 1
Client:2 /127.0.0.1: Message 2
Client:3 /127.0.0.1: Message 2
Client:4 /127.0.0.1: Message 2
Client:5 /127.0.0.1: Message 2
Client:6 /127.0.0.1: Message 2
Client:7 /127.0.0.1: Message 2
Client:8 /127.0.0.1: Message 2
Client:2 /127.0.0.1: Message 3
Client:3 /127.0.0.1: Message 3
Client:4 /127.0.0.1: Message 3
Client:5 /127.0.0.1: Message 3
Client:6 /127.0.0.1: Message 3
Client:7 /127.0.0.1: Message 3
Client:8 /127.0.0.1: Message 3
Client:2 /127.0.0.1: exit
Client:2 Asked to exit. Leaving connection
Client:3 /127.0.0.1: exit
Client:3 Asked to exit. Leaving connection
Client:4 /127.0.0.1: exit
Client:4 Asked to exit. Leaving connection
Client:5 /127.0.0.1: exit
Client:5 Asked to exit. Leaving connection
Client:6 /127.0.0.1: exit
Client:6 Asked to exit. Leaving connection
Client:7 /127.0.0.1: exit
Client:7 Asked to exit. Leaving connection
Client:8 /127.0.0.1: exit
Client:8 Asked to exit. Leaving connection
9 Client connected
Main Thread: Waiting for client to connect...
Client:9 /127.0.0.1: Message 1
10 Client connected
Main Thread: Waiting for client to connect...
Client:10 /127.0.0.1: Message 1
11 Client connected
Main Thread: Waiting for client to connect...
Client:11 /127.0.0.1: Message 1
Client:9 /127.0.0.1: Message 2
Client:10 /127.0.0.1: Message 2
Client:11 /127.0.0.1: Message 2
Client:9 /127.0.0.1: Message 3
Client:10 /127.0.0.1: Message 3
Client:11 /127.0.0.1: Message 3
12 Client connected
Main Thread: Waiting for client to connect...
Client:12 /127.0.0.1: Message 1
Client:9 /127.0.0.1: exit
Client:9 Asked to exit. Leaving connection
Client:10 /127.0.0.1: exit
Client:10 Asked to exit. Leaving connection
Client:11 /127.0.0.1: exit
Client:11 Asked to exit. Leaving connection
Client:12 /127.0.0.1: Message 2
Client:12 /127.0.0.1: Message 3
Client:12 /127.0.0.1: exit
Client:12 Asked to exit. Leaving connection

I am using eclipse IDE and to simulate the above, i first ran the server. after that just run the client file mulitple time simultaneously. I have used a delay in client side of 0.5 sec, so each client sends the message 0.5 sec later a total of 3 messages are sent from client and in 4th message, client asks to break the connection. While one client is running, another client also sends the message and this simulates the use case asked by you,

Thanks