/** * A client that can be run from anywhere. If the server is running, the following command starts up the client: * java MyClient numThreads * numThreads is an optional number of threads you want the current machine to use, if not specified, program * will use as many threads as there are cores on your machine. * The majority of this code does not need to be modified. However, there are several places that can be customized depending on your needs: * 1. Port number on line 23. Change if you want to connect on a different port. * 2. The hashcode on line 79-87. You may want to simply sent a "version number" to the server to ensure the newest client is always running. * 3. The "solving" of the cases in lines 96-101. In this template, a case is "solved" by sleeping between 5-10 seconds. In reality, you'll want to do your actually solving of the case here. * 4. The response from the client to the server on line 104. In this template, the response is ignored on the server side and a new case is sent to the client. If the response from the client is important and needs to be remembered, this information is sent in line 104. */ import java.net.*; import java.io.*; import java.util.*; import java.nio.file.*; import java.security.MessageDigest; public class MyClient { private static boolean keepGoing; private static int portNumber = 9450; /** * Main method that waits for clients to connect. Usage: * * java MyClient serverAddress numberOfThreads * * @param serverAddress The ip address of the server the client is connecting to. * @param numberOfThreads Optional argument to specify number of threads the client should use. */ public static void main(String[] args) throws Exception{ keepGoing = true; //Automatically set number of threads equal to number of processors. int numberOfThreads = Runtime.getRuntime().availableProcessors(); //Change number of threads if user specifies a thread count. if(args.length==2){ numberOfThreads = Integer.parseInt(args[1]); } //Start threads System.out.println("Starting "+numberOfThreads+" threads."); for(int i = 0; i < numberOfThreads; i++){ new MyThread(args[0]).start(); } while(keepGoing){ //Make sure number of running threads is what we wanted. The "main" thread isn't actually doing //any work so having it run along with numberOfThreads threads is why it's numberOfThreads+1. while(Thread.activeCount() < numberOfThreads+1){ //If a thread died, somehow, start a new thread. System.out.println("Started a new thread."); new MyThread(args[0]).start(); } //Sleep for a minute. It is possible a thread fails for some reason, e.g. loses network connection. Thread.currentThread().sleep(60000); } } public static class MyThread extends Thread { public String ipAddress; public MyThread(String ipAddress){ this.ipAddress = ipAddress; } public void run() { try{ //Administrative stuff to connect with the server. BufferedReader in; PrintWriter out; Socket socket = new Socket(ipAddress, portNumber); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(), true); String response = in.readLine(); if(response.equals("Verify")){ //Send hashcode of current class to the server. byte[] file = Files.readAllBytes(FileSystems.getDefault().getPath("MyClient$MyThread.class")); MessageDigest md = MessageDigest.getInstance("SHA-1"); md.update(file); String result = ""; for(byte b : md.digest()){ result += String.format("%02x", b); } //If less concerned about having a secure client, can send a version number (or something) to the server to ensure the client is the correct client. out.println(result); response = in.readLine(); if(response.equals("PASSED")){ //Start working on cases. String nextCase = in.readLine(); while(!nextCase.equals("FINISHED")){ //Solve nextCase. //In this template, the solving of the case is simply //sleeping between 5 and 10 seconds. In general, you will //want to do something to solve the case. try{ Random r = new Random(); Thread.currentThread().sleep(5000+r.nextInt(5000)); }catch(Exception e){ e.printStackTrace(); } System.out.println("Solved case "+nextCase+"."); //finished solving nextCase, tell the server, get new case. out.println("CaseComplete"); nextCase = in.readLine(); } System.out.println("No more cases left to compute."); keepGoing = false; } else{ //Server kicked us out, we didn't provide correct details. Kill all threads. keepGoing = false; System.out.println("Client is incorrect, stop all threads."); return; } } } catch(Exception e){ System.out.println("Got an exception: " + e); e.printStackTrace(); } } } }