· 5 years ago · Nov 14, 2019, 08:18 PM
1
2// Multi-threaded Client program
3// File name: jb_TCPClientMT.java
4// Programmer: Jacob Bray
5//October 24, 2019
6
7import java.io.*;
8import java.net.*;
9import java.util.Scanner;
10
11public class jb_TCPClientMT {
12 private static InetAddress host;
13 // private static String user;
14
15 public static void main(String[] args) {
16 String user = "";
17 Scanner input = new Scanner(System.in);
18 int port = 20500;
19
20 try {
21 host = InetAddress.getByName("localhost");
22 } catch (UnknownHostException e) {
23
24 e.printStackTrace();
25 }
26
27 for (int i = 0; i < args.length - 1; i++) {
28 if (args[i].equals("-u")) {
29 user = args[i + 1];
30 }
31 if (args[i].equals("-h")) {
32 try {
33 host = InetAddress.getByName(args[i + 1]);
34 } catch (UnknownHostException e) {
35 System.out.println("Host ID not found!");
36 System.exit(1);
37 }
38 }
39 if (args[i].equals("-p")) {
40 port = Integer.parseInt(args[i + 1]);
41 }
42
43 i++;
44 }
45 // Prompt the user for a username if not provided from command line
46 if (user.equals("")) {
47 System.out.println("Please enter a username: ");
48 user = input.nextLine();
49 }
50 System.out.println("Connecting with the following settings:\nUsername: " + user + "\nHost: " + host.toString()
51 + "\nPort: " + port + "\n");
52
53 run(port, user);
54 input.close();
55 }
56
57 //Return a^b mod c
58 static int exponentMod(int a, int b, int c) {
59
60 // Base cases
61 if (a == 0)
62 return 0;
63 if (b == 0)
64 return 1;
65
66 // If B is even
67 long y;
68 if (b % 2 == 0) {
69 y = exponentMod(a, b / 2, c);
70 y = (y * y) % c;
71 }
72
73 // If B is odd
74 else {
75 y = a % c;
76 y = (y * exponentMod(a, b - 1, c) % c) % c;
77 }
78
79 return (int) ((y + c) % c);
80 }
81
82 public static String crypt(String message, byte pad) {
83 byte[] messageBytes = message.getBytes();
84 message = "";
85 for(int i = 0; i < messageBytes.length; i++) {
86 messageBytes[i] = (byte) (messageBytes[i] ^ pad);
87 message = (message + (char) messageBytes[i]);
88 }
89 return message;
90 }
91
92
93 private static void run(int port, String user) {
94
95 Socket link = null;
96 try {
97 // Establish a connection to the server using the provided host and port number
98 link = new Socket(host, port);
99
100 // Set up input and output streams for the connection
101 BufferedReader in = new BufferedReader(new InputStreamReader(link.getInputStream()));
102 PrintWriter servOut = new PrintWriter(link.getOutputStream(), true);
103
104 //Diffie-Hellman Handshake
105 int n, g, gX, x, y;
106 //Pick a random number between 100 and 200
107 y = (int)(Math.random() * ((200 - 100) + 1)) + 100;
108 //Read n from the server
109 n = Integer.parseInt(in.readLine());
110 //Read g from the server
111 g = Integer.parseInt(in.readLine());
112 //Read g^x mod n from the server
113 gX = Integer.parseInt(in.readLine());
114
115 //Send g^y mod n to the server
116 servOut.println(exponentMod(g, y, n));
117
118 int secretKey = exponentMod(gX, y, n);
119 byte pad = (byte) secretKey;
120
121 System.out.println("****Server Info****");
122 System.out.println("n: "+n);
123 System.out.println("g: "+g);
124 System.out.println("Session Key: "+secretKey);
125 System.out.println("Byte pad: "+pad);
126
127
128 String message = "";
129 // First send the username to the server
130 servOut.println(crypt(user, pad));
131
132 //Receive the contents of the chat file from the server
133 int numMessages = Integer.parseInt(crypt(in.readLine(), pad));
134 for (int k = 0; k < numMessages; k++) {
135
136 System.out.println(crypt(in.readLine(), pad));
137
138 }
139 // Create the writeHandler thread object
140 jb_WriteHandler serverOut = new jb_WriteHandler(link, servOut, pad);
141 jb_ReadHandler serverIn = new jb_ReadHandler(link, in, pad);
142
143 // Start the thread to handle output to the server
144 serverOut.start();
145 serverIn.start();
146
147
148
149 } catch (IOException e) {
150 e.printStackTrace();
151 }
152 // Close the connection to the server, display an error message and exit if
153 // unable to disconnect
154 finally {
155 try {
156 System.out.println("\n!!!!! Closing connection... !!!!!");
157 link.close();
158 }
159
160 catch (IOException e) {
161 System.out.println("Unable to disconnect!");
162 System.exit(1);
163 }
164
165 }
166
167 }
168
169}
170
171class jb_ReadHandler extends Thread {
172 Socket server;
173 BufferedReader in;
174 byte pad;
175
176 public jb_ReadHandler(Socket s, BufferedReader in, byte pad) throws IOException {
177 this.in = in;
178 this.server = s;
179 this.pad = pad;
180
181 }
182 //Encrypt plaintext, or decrypt an encrypted message
183 public static String crypt(String message, byte pad) {
184 byte[] messageBytes = message.getBytes();
185 message = "";
186 for(int i = 0; i < messageBytes.length; i++) {
187 messageBytes[i] = (byte) (messageBytes[i] ^ pad);
188 message = (message + (char) messageBytes[i]);
189 }
190 return message;
191 }
192
193 public void run() {
194 String message = null;
195 try {
196 message = crypt(in.readLine(), pad);
197 // Run until the server responds with DONE
198 while (!message.equals("DONE")) {
199
200 message = crypt(in.readLine(), pad);
201 System.out.println(message);
202
203 }
204
205 // Receive the final report and connection time from the server
206 System.out.println("am I even getting here");
207 message = crypt(in.readLine(), pad);
208 System.out.println(message);
209 message = crypt(in.readLine(), pad);
210 System.out.println(message);
211 message = crypt(in.readLine(), pad);
212 System.out.println(message);
213 message = crypt(in.readLine(), pad);
214
215 //in.close();
216
217 } catch (IOException e) {
218 e.printStackTrace();
219 }
220
221 }
222
223}
224
225//Handles output to the server
226class jb_WriteHandler extends Thread {
227 private PrintWriter servOut;
228 Socket server;
229 byte pad;
230
231 // Constructor that runs automatically when thread is creates
232 public jb_WriteHandler(Socket s, PrintWriter servOut, byte pad) {
233 this.server = s;
234 this.pad = pad;
235 this.servOut = servOut;
236 return;
237
238 }
239
240 public static String crypt(String message, byte pad) {
241 byte[] messageBytes = message.getBytes();
242 message = "";
243 for(int i = 0; i < messageBytes.length; i++) {
244 messageBytes[i] = (byte) (messageBytes[i] ^ pad);
245 message = (message + (char) messageBytes[i]);
246 }
247 return message;
248 }
249
250 public void run() {
251 // Create user input scanner and message string
252 Scanner input = new Scanner(System.in);
253 String message = "";
254 // Send messages to server until user enters DONE
255 while (!message.equals("DONE")) {
256 System.out.println("Start of loop, message is currently: "+message);
257 System.out.println("Enter message: ");
258 message = input.next();
259 System.out.println("Sending: "+message+" to the server");
260 servOut.println(crypt(message, pad));
261 }
262
263 input.close();
264 }
265
266}