- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTCPClientMT.java
More file actions
Latest commit
334 lines (299 loc) · 9.75 KB
/
Copy pathTCPClientMT.java
File metadata and controls
334 lines (299 loc) · 9.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
/*
Name: Joshua Kuiper
Project Description:
This is a multithreaded client/server program.
Many clients can connect to one server, and contents of their chat in a chat room
is stored with in a chat file which is created if a user joins an empty chat room,
displays to all users when they join, and deletes if they're the last one to leave.
Programmer: COSC 439/522, F '21
Multi-threaded Client program
File name: TCPClientMT.java
When you run this program, you must give both the host name and
the service port number as command line arguments. For example,
java TCPClientMT -u User -p 20600 -h Localhost
*/
importjava.io.*;
importjava.net.*;
importjava.nio.charset.StandardCharsets;
importjava.util.Arrays;
publicclassTCPClientMT{
privatestaticInetAddresshost;
staticlongstartTime = System.currentTimeMillis();
publicstaticvoidmain(String[] args){
StringportNumber = "";
StringhostName = "";
Stringuser = "";
//User arguments
try {
for(inti = 0; i < args.length; i++) {
if(args[i] != null) {
if(args[i].equals("-p")) {
portNumber = args[i+1];
}
elseif(args[i].equals("-u")) {
user = args[i+1];
}
elseif(args[i].equals("-h")) {
hostName = args[i+1];
}
/*
I know you said we need to do this but if you uncomment this,
The only way for it to work is by not giving any arguments.
It always complains and I couldn't figure it out...
else{
System.out.println("Invalid Input!");
System.exit(0);
}
*/
}
}
//If user doesn't enter username
if(user == "") {
try{
BufferedReaderuserEntry = newBufferedReader(newInputStreamReader(System.in));
Stringmessage;
System.out.print("Username required: ");
message = userEntry.readLine();
user = message;
}catch(Exceptione){
e.printStackTrace();
}
}
//Defaults if no host or port is entered
if(hostName == "") {
hostName = "localhost";
}
if(portNumber == "") {
portNumber = "20600";
}
// Get server IP-address
host = InetAddress.getByName(hostName);
//Catches unknown host
}catch(UnknownHostExceptione){
System.out.println("Host ID not found!");
System.exit(1);
}
run(Integer.parseInt(portNumber), user);
}
//Runs the client
privatestaticvoidrun(intport, Stringuser){
Socketlink = null;
try{
// Establish a connection to the server
link = newSocket(host,port);
// Set up input and output streams for the connection
BufferedReaderin = newBufferedReader(
newInputStreamReader(link.getInputStream()));
PrintWriterout = newPrintWriter(
link.getOutputStream(),true);
// Create a sender thread. This thread reads messages typed at the keyboard
// and sends them to the server
Sendersender = newSender(out, user);
// Start the sender thread
sender.start();
// The main thread reads messages sent by the server, and displays them on the screen
Stringmessage;
// Get data from the server and display it on the screen
intnumMessages = 0;
intprivateKey = (int)((Math.random() * (201 - 100)) + 100);
Stringgee = "1";
Stringnee = "1";
//Gets the generated key
longgenKey = 1;
//Secret key for Server
longsecretKey = 1;
try{
while (!(message = in.readLine()).equals("Done")){
if(numMessages == 0){
gee = message.substring(0, 4);
nee = message.substring(5, 9);
genKey = power(Long.parseLong(gee), privateKey, Long.parseLong(nee));
secretKey = power(genKey, privateKey, Long.parseLong(nee));
System.out.println("Handshake complete. G: " + gee + " N: " + nee + " Session Key: " + secretKey + " Byte Pad: "
+ convertAsciiToBinary(convertToAscii(String.valueOf(privateKey))).substring(0, 8));
}
if(!(message.contains("established"))){
if(message.contains("10")){
System.out.println(decrypt(message,(int)secretKey));
}
else{
System.out.println(message);
}
}
//If the message is "Done", print the total run time.
//Computes the system time that the user was in the server.
if((message = in.readLine()).equals("Done")){
longendTime = System.currentTimeMillis();
longmils = endTime - startTime;
intleftOver = (int) mils % 1000;
intseconds = (int) (mils / 1000) % 60;
intminutes = (int) ((mils / (1000*60)) % 60);
inthours = (int) ((mils / (1000*60*60)) % 24);
System.out.println("Total run time: " + hours + "h::" + minutes + "m::" + seconds + "s::" + leftOver + "ms");
}
numMessages++;
}
//Catches errors
}catch(NullPointerExceptione){
}
}catch(IOExceptione){
}
finally{
try{
System.out.println("\n!!!!! Closing connection... !!!!!");
link.close();
}catch(IOExceptione){
System.out.println("Unable to disconnect!");
System.exit(1);
}
}
}
// Power function to return value of a ^ b mod N
privatestaticlongpower(longa, longb, longN){
if (b == 1)
returna;
else
return (((long)Math.pow(a, b)) % N);
}
/*
* The following methods are all for the encryption and
* decryption of all messages sent / received.
*/
//Encrypts the string
publicstaticStringencrypt(Stringmessage, intkey) {
Stringencrypted = "";
//Convert key to binary number
StringbinaryKey = Integer.toBinaryString(key);
binaryKey = binaryKey.substring(binaryKey.length() - 8);
//Converts the string to ascii, then to binary
StringnewMessage = convertToAscii(message);
newMessage = convertAsciiToBinary(newMessage);
//Creates array of encrypted words
String[] binaryArray = newMessage.split(" ");
String[] encryptedWords = newString[binaryArray.length];
for(inti = 0; i < binaryArray.length; i++) {
encryptedWords[i] = binaryAdd(binaryArray[i], binaryKey);
}
//Adds encrypted words all into one string
for(intq = 0; q < encryptedWords.length; q++) {
encrypted += encryptedWords[q] + " ";
}
returnencrypted;
}
//Decrypts the encrypted string
publicstaticStringdecrypt(Stringmessage, intkey) {
Stringdecrypted = "";
//Convert key to binary number
StringbinaryKey = Integer.toBinaryString(key);
binaryKey = binaryKey.substring(binaryKey.length() - 8);
//Converts encrypted binary to decrypted binary
String[] decryptedWords = message.split(" ");
for(inti = 0; i < decryptedWords.length; i++) {
decryptedWords[i] = binaryAdd(decryptedWords[i], binaryKey);
}
//Converts binary to ascii
String[] asciiWords = newString[decryptedWords.length];
for(intj = 0; j < decryptedWords.length; j++) {
inttemp = Integer.parseInt(decryptedWords[j],2);
asciiWords[j] = String.valueOf(temp);
}
//Converts array to string to be decrypted
for(intq = 0; q < decryptedWords.length; q++) {
decrypted += asciiWords[q] + " ";
}
//Converts the ascii to binary
decrypted = convertBack(decrypted);
returndecrypted;
}
//Does binary addition for encryption
publicstaticStringbinaryAdd(Stringword, Stringkey){
StringnewString = "";
for (inti = 0; i < 8; i++){
if (word.charAt(i) == key.charAt(i))
newString += "0";
else
newString += "1";
}
returnnewString;
}
//Converts words to ascii characters
publicstaticStringconvertToAscii(Stringmessage) {
byte[] ascii = message.getBytes(StandardCharsets.US_ASCII);
StringasciiString = Arrays.toString(ascii);
asciiString = removeJunk(asciiString);
returnasciiString;
}
//Converts Ascii characters to binary
publicstaticStringconvertAsciiToBinary(Stringascii) {
Stringbinary = "";
String[] arr = ascii.split(" ");
String[] converted = newString[arr.length];
//Converts all ascii values to binary
for(inti = 0; i < converted.length; i++) {
intnum = Integer.valueOf(arr[i]);
converted[i] = Integer.toBinaryString(num);
}
//Adds 0's to front of binary numbers if they're shorter 8
for(intj = 0; j < converted.length; j++) {
while(converted[j].length() < 8) {
converted[j] = "0" + converted[j];
}
}
//Converts string array to string
for(intq = 0; q < converted.length; q++) {
binary += converted[q] + " ";
}
returnbinary;
}
//Makes string pretty
publicstaticStringremoveJunk(Stringmessage) {
//Removes junk from string
StringnewMessage = message.replaceAll(",", "");
newMessage = newMessage.replaceAll("\\[", "");
newMessage = newMessage.replaceAll("\\]", "");
returnnewMessage;
}
//Converts ascii to real characters
publicstaticStringconvertBack(Stringmessage) {
StringconvertedMessage = "";
//Split string on spaces and convert from ascii values to letters
String[] arr = message.split(" ");
for(Stringstr: arr) {
intnum = (Integer.valueOf(str));
chara = (char)num;
convertedMessage += "" + a;
}
returnconvertedMessage;
}
}
// The sender class reads messages typed at the keyboard, and sends them to the server
classSenderextendsThread{
privatePrintWriterout;
Stringusername = "";
publicSender (PrintWriterout, Stringuser){
this.out = out;
username = user;
}
// overwrite the method 'run' of the Runnable interface
// this method is called automatically when a sender thread starts.
publicvoidrun(){
//Set up stream for keyboard entry
BufferedReaderuserEntry = newBufferedReader(newInputStreamReader(System.in));
Stringmessage;
// Get data from the user and send it to the server
try {
intcount = 0;
if(count <= 0)
out.println(username);
count = 1;
do{
System.out.print("Enter message: ");
message = userEntry.readLine();
out.println(message);
}while (!message.equals("DONE"));
}
catch(IOExceptione){
e.printStackTrace();
}
}
}