-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConnection.java
More file actions
377 lines (331 loc) · 12 KB
/
Connection.java
File metadata and controls
377 lines (331 loc) · 12 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
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
package Chat;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import org.apache.commons.lang3.StringEscapeUtils;
/**
*Abstract class for client/server connection methods
* @author joar
*/
public abstract class Connection {
/**
*Hash map with stored cryptos for each socket
*/
protected HashMap<Socket, Crypto> cryptos = new HashMap();
/**
*List of sockets
*/
protected ArrayList<Socket> sockets = new ArrayList();
/**
*Hash map with stored names for each socket
*/
protected HashMap<Socket, String> names = new HashMap();
/**
*true == multi conversation
*/
protected boolean multiConversation = false;
private static int port = 1025;
/**
*Gets a new port
* @return port as string
*/
public String getPort() {
port++;
if(port > 65534) {
port = 1025;
}
return Integer.toString(port);
}
/**
*Sends a message to all sockets
* @param message message to be sent
* @param name name of the sender
* @param color color of font
* @param sendCryptoStart in encryption start should be sent
* @throws Exception
*/
public void sendMessage(String message, String name,
String color, boolean sendCryptoStart) throws Exception {
for(Socket socket: sockets) {
sendMessage(socket, message, name, color, sendCryptoStart);
}
}
/**
*Sends a message to every socket except a specified socket
* @param socket Socket not to be sent to
* @param message message to be sent
* @param name name of the sender
* @param color color of font
* @throws Exception
*/
public void sendOtherClients(Socket socket, String message, String name,
String color) throws Exception {
for(Socket tmpSocket: sockets) {
if(!socket.equals(tmpSocket)) {
sendMessage(tmpSocket, message, name, color, false);
}
}
}
public void sendDisconnect(Socket socket, String name,
String self) throws Exception {
String message = name + " has logged of";
for(Socket tmpSocket: sockets) {
if(!socket.equals(tmpSocket)) {
sendMessage(tmpSocket, message, self, "", false);
}
}
}
/**
*Sends a message to every socket
* @param socket The Socket to send to
* @param message message to be sent
* @param name name of the sender
* @param color color of font
* @param sendCryptoStart in encryption start should be sent
* @throws Exception
*/
public void sendMessage(Socket socket, String message, String name,
String color, boolean sendCryptoStart) throws Exception {
if(!sockets.contains(socket)) {
return;
}
message = StringEscapeUtils.escapeHtml3(message);
StringBuilder outgoing = new StringBuilder();
StringBuilder innerMessage = new StringBuilder();
if( !"".equals(name)){
outgoing.append(Constants.MESSAGE_NAME).append(name).append(">");
}
else{
outgoing.append(Constants.MESSAGE_START);
}
if(!"".equals(color)){
innerMessage.append(Constants.TEXT_COLOR).append(color).append(">");
}
else{
innerMessage.append(Constants.TEXT_START);
}
innerMessage.append(message).append(Constants.TEXT_STOP);
if(hasCrypto(socket)) {
Crypto crypto = getCrypto(socket);
String encoded;
if(sendCryptoStart) {
outgoing.append(Constants.ENCRYPTED_TYPE).
append(crypto.getType()).append(" key=")
.append(crypto.getKey()).append(">");
}
else{
outgoing.append(Constants.ENCRYPTED_TYPE)
.append(crypto.getType()).append(">");
}
try {
encoded = crypto.encodeMessage(innerMessage.toString());
outgoing.append(encoded);
outgoing.append(Constants.ENCRYPTED_STOP);
}
catch (Exception ex) {
deleteCrypto(socket);
outgoing.append(innerMessage.toString());
}
}
else{
outgoing.append(innerMessage.toString());
}
outgoing.append(Constants.MESSAGE_STOP);
send(socket, outgoing.toString());
}
/**
*Returns true if a Socket has a crypto
* @param socket Socket
* @return boolean
*/
public boolean hasCrypto(Socket socket) {
return cryptos.containsKey(socket);
}
/**
* Gets the crypto for the Socket
* @param socket Socket
* @return The specified Crypto
*/
public Crypto getCrypto(Socket socket) {
return cryptos.get(socket);
}
/**
*Sets a Crypto
* @param socket Socket to set Crypto for
* @param type Type of crypto
* @throws Exception raised if unable to set crypto
*/
public void setCrypto(Socket socket, String type) throws Exception {
cryptos.put(socket, new Crypto(type));
}
/**
*Removes the crypto to corresponding socket
* @param socket the Socket
*/
public void deleteCrypto(Socket socket) {
cryptos.remove(socket);
}
/**
*Set name for a socket
* @param socket the Socket
* @param name the name
*/
public void setName(Socket socket, String name) {
names.put(socket, name);
}
/**
* Get name for corresponding socket
* @param socket the Socket
* @return the name
*/
public String getName(Socket socket) {
if(names.containsKey(socket)) {
return names.get(socket);
}
return socket.getInetAddress().toString();
}
/**
*Sends a file request to specified Socket
* @param socket the Socket
* @param message explanatory message
* @param name senders name
* @param fileName the file name
* @param size the file size
* @throws Exception
*/
public void sendFileTransferRequest(Socket socket, String message,
String name, String fileName, String size) throws Exception {
message = StringEscapeUtils.escapeHtml3(message);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(Constants.FILE_REQUEST_NAME).append(fileName)
.append(" size=").append(size).append(">")
.append(message).append(Constants.FILE_REQUEST_STOP);
sendEncrypted(socket, stringBuilder.toString(), name);
}
/**
*Reply to an file request to a specified Socket
* @param socket the Socket
* @param name name of sender
* @param answer the reply = yes/no
* @param reason reason for answer
* @param port port to send to, otherwise ""
* @param type type of encryption if desired, otherwise ""
* @param key key to encryption, otherwise ""
* @throws Exception
*/
public void replyFileTransfer(Socket socket, String name, String answer,
String reason, String port, String type, String key)
throws Exception {
reason = StringEscapeUtils.escapeHtml3(reason);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(Constants.FILE_RESPONES).append(answer)
.append(" port=").append(port).append(" type=").append(type)
.append(" key=").append(key).append(">")
.append(reason).append(Constants.FILE_RESPONSE_STOP);
sendEncrypted(socket, stringBuilder.toString(), name);
}
/**
*Sends a key request to specified socket
* @param socket the Socket
* @param message explanatory message
* @param name the senders name
* @param type typo of key desired
* @throws Exception
*/
public void sendKeyRequest(Socket socket, String message, String name,
String type) throws Exception {
message = StringEscapeUtils.escapeHtml3(message);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(Constants.KEY_REQUEST).append(type).append(">")
.append(message).append(Constants.KEY_REQUEST_STOP);
sendEncrypted(socket, stringBuilder.toString(), name);
}
/**
*Sends a key to specified Socket
* @param socket the Socket
* @param name senders name
* @throws Exception
*/
public void sendKey(Socket socket, String name)
throws Exception {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(Constants.MESSAGE_NAME).append(name).append(">");
stringBuilder.append(Constants.KEY_RESPONSE)
.append(getCrypto(socket).getType()).append(" key=")
.append(getCrypto(socket).getKey()).append(">")
.append(Constants.KEY_RESPONSE_STOP);
stringBuilder.append(Constants.MESSAGE_STOP);
send(socket, stringBuilder.toString());
}
/**
*Sends an answer to a join request to a conversation to specified Socket
* @param socket the socket
* @param name name of sender
* @param ans the answer = yes/no
* @throws Exception
*/
public void sendJoinReply(Socket socket, String name, String ans)
throws Exception {
String outgoing = Constants.REQUEST_ANS + ans +">"
+ Constants.REQUEST_STOP;
sendEncrypted(socket, outgoing, name);
}
/**
*Sends a join request to a conversation to a specified Socket
* @param message explanatory message for request
* @param name name of sender
* @throws Exception
*/
public void sendJoinRequest(String message, String name)
throws Exception {
for(Socket socket: sockets) {
String outgoing = Constants.REQUEST + message +
Constants.REQUEST_STOP;
sendEncrypted(socket, outgoing, name);
}
}
/**
*Disconnect from conversation
* @throws Exception
*/
public void disconnect(String name) throws Exception {
for(Socket socket: sockets) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(Constants.MESSAGE_NAME)
.append(name).append(">");
stringBuilder.append(Constants.DISCONNECT)
.append(Constants.MESSAGE_STOP);
send(socket, stringBuilder.toString());
}
}
private void sendEncrypted(Socket socket, String message, String name)
throws Exception {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(Constants.MESSAGE_NAME).append(name).append(">");
if(hasCrypto(socket)) {
Crypto crypto = getCrypto(socket);
stringBuilder.append(Constants.ENCRYPTED_TYPE)
.append(crypto.getType()).append(">")
.append(crypto.encodeMessage(message))
.append(Constants.ENCRYPTED_STOP);
}
else {
stringBuilder.append(message);
}
stringBuilder.append(Constants.MESSAGE_STOP);
OutputStreamWriter output =new OutputStreamWriter(
socket.getOutputStream(), "UTF-8");
output.write(stringBuilder.toString(), 0,
stringBuilder.toString().length());
output.flush();
}
private void send(Socket socket, String message)
throws Exception {
OutputStreamWriter output =new OutputStreamWriter(
socket.getOutputStream(), "UTF-8");
output.write(message, 0, message.length());
output.flush();
}
}