Advertisement
Guest User

Untitled

a guest
Mar 30th, 2017
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.53 KB | None | 0 0
  1. import javax.swing.*;
  2. import java.io.*;
  3. import java.net.*;
  4. import java.util.*;
  5. import java.util.concurrent.ConcurrentHashMap;
  6.  
  7. public class PictureChatServer implements Runnable
  8. {
  9. public static void main(String[] args) throws Exception
  10. {
  11. if (args.length > 0)
  12. System.out.println("Command line parameters are not accepted by ChatServer.");
  13. new PictureChatServer();
  14. }
  15.  
  16. private ServerSocket ss;
  17. private int serverPort = 6666;
  18.  
  19. // key will be the chat name of user in the chat room.
  20. // the associated String will be the password for that chatName.
  21. private ConcurrentHashMap<String,String> clients =
  22. new ConcurrentHashMap<String,String>();
  23. private ConcurrentHashMap<String,ObjectOutputStream> whosIn =
  24. new ConcurrentHashMap<String,ObjectOutputStream>();
  25. private Vector<String> whosNotIn;
  26. private ConcurrentHashMap<String, Vector<Object>> savedMessages =
  27. new ConcurrentHashMap<String, Vector<Object>>();
  28.  
  29.  
  30. //========================================================
  31. public PictureChatServer() throws Exception // CONSTRUCTOR
  32. {
  33. // System.out.println("***********************************************************");
  34. System.out.println("ECE 309 Lab6 PrivateChatServer\nSpring 2017\nAuthor: Nivesh Varma\n");
  35. // System.out.println("***********************************************************");
  36.  
  37. ss = new ServerSocket(serverPort);
  38.  
  39. // restore the SavedMessages collection from disk.
  40. try {
  41. FileInputStream fis = new FileInputStream("Messages.ser");
  42. ObjectInputStream ois = new ObjectInputStream(fis);
  43. savedMessages = (ConcurrentHashMap<String,Vector<Object>>) ois.readObject();
  44. ois.close();
  45. }
  46. catch(FileNotFoundException fnfe)
  47. {
  48. System.out.println("Messages.ser is not found, so an empty collection will be used.");
  49. }
  50. System.out.println("Messages previously saved for clients are:");
  51. System.out.println(savedMessages);
  52.  
  53. // restore the clients collection from disk that has the passwords.
  54. try {
  55. FileInputStream fis = new FileInputStream("clients.ser");
  56. ObjectInputStream ois = new ObjectInputStream(fis);
  57. clients = (ConcurrentHashMap<String,String>) ois.readObject();
  58. ois.close();
  59. }
  60. catch(FileNotFoundException fnfe)
  61. {
  62. System.out.println("clients.ser is not found, so an empty collection will be used.");
  63. }
  64. System.out.println("Previously in the chat room: ");
  65. System.out.println(clients);
  66. // all previous clients are
  67. whosNotIn = new Vector(clients.keySet());// who is not in the chat room
  68. // when the server comes up.
  69. System.out.println("ChatServer is up at "
  70. + InetAddress.getLocalHost().getHostAddress()
  71. + " on port " + ss.getLocalPort());
  72.  
  73. new Thread(this).start(); // create 1st client Thread
  74. } // to execute run() method.
  75.  
  76. //=========================================================
  77. /** Each client goes through 4 stages:
  78. * 1. connection processing
  79. * 2. join processing
  80. * 3. send/receive processing
  81. * 4. leave processing
  82. * (See these sections in the run() method below.)
  83. */
  84. public void run()//each client application thread enters here!
  85. {
  86. Socket s = null;
  87. ObjectInputStream ois = null;
  88. ObjectOutputStream oos = null;
  89. String firstMessage = null;
  90. String chatName = null;
  91. String enteredPassword = null;
  92. String clientAddress = null;
  93. try {
  94. s = ss.accept(); // wait for next client to connect
  95. ois = new ObjectInputStream(s.getInputStream());
  96. firstMessage = (String) ois.readObject();
  97. oos = new ObjectOutputStream(s.getOutputStream());
  98. }
  99. catch(Exception e) // client protocol is not oos
  100. { // or firstMessage is not a String
  101. if (s != null)
  102. clientAddress = s.getInetAddress().getHostAddress();
  103. System.out.println("Connect/join exception from " + clientAddress);
  104. return; // terminate this client thread
  105. }
  106. finally
  107. {
  108. new Thread(this).start();
  109. }
  110. // If we are still running here s, ois, oos, and firstMessage are all good!
  111. // Whether catch was entered or NOT, a new thread has been created and has entered run().
  112. try {
  113. System.out.println("First message received: " + firstMessage);
  114. int spaceOffset = firstMessage.indexOf(" ");
  115. if (spaceOffset < 0)
  116. {
  117. oos.writeObject("Invalid format. " // 1) send err msg
  118. + "Are you calling the right address and port?");
  119. oos.close(); // 2) hang up
  120. System.out.println("Invalid 1st message received (no space separator): " + firstMessage);
  121. return; // 3) kill this client thread.
  122. }
  123. chatName = firstMessage.substring(0,spaceOffset).toUpperCase();
  124. enteredPassword = firstMessage.substring(spaceOffset).trim();
  125. if (enteredPassword.contains(" "))
  126. {
  127. oos.writeObject("Invalid format. " // 1) send err msg
  128. + "Are you calling the right address and port?");
  129. oos.close(); // 2) hang up
  130. System.out.println("Invalid 1st message received (space in name or pw): " + firstMessage);
  131. return; // 3) kill this client thread.
  132. }
  133.  
  134. if (clients.containsKey(chatName)) // this name already in?
  135. {
  136. String storedPassword = clients.get(chatName);
  137. if (!enteredPassword.equals(storedPassword))
  138. {
  139. oos.writeObject("Your entered password " + enteredPassword + " is not the same as the password stored for chat name " + chatName);
  140. oos.close(); // hang up.
  141. System.out.println("Invalid password: " + enteredPassword + " instead of " + storedPassword);
  142. return; // and kill this client thread
  143. }
  144. }
  145. else // this chatName has never joined
  146. { // so join them!
  147. clients.put(chatName, enteredPassword);
  148. saveChatNames();
  149. }
  150.  
  151. // 2. "JOIN processing" for this client
  152. oos.writeObject("Welcome to the chat room " + chatName + "!"); // confirm to client that they are in!
  153. // note that if write above fails, put & send below doesn't happen...
  154. // Is this a RECONNECT? (a re-join from a new location of
  155. // someone that was ALREADY IN the char room?
  156. if (!whosIn.containsKey(chatName)) // not already in
  157. {
  158. sendToAllClients("Welcome to " + chatName + " who has just joined the chat room!");
  159. whosIn.put(chatName,oos); // add new-join client to whosIn collection
  160. whosNotIn.remove(chatName); // and remove from WhosNotIn list.
  161. System.out.println(chatName + " is joining");
  162. }
  163. else // THIS CLIENT IS ALREADY IN THE CHAT ROOM!
  164. // e.g. This person left work without leaving the chat
  165. // room and is now signing on from home. We know it is
  166. // them because they passed the password test above.
  167. // So we are going to SHUT DOWN their old session, and
  168. // then REPLACE their old oos in the clients collection
  169. // with their new oos.
  170. {
  171. ObjectOutputStream oldOOS = whosIn.get(chatName);
  172. whosIn.replace(chatName, oos); // don't delay!
  173. oldOOS.writeObject("Session shut down due to rejoin from new location.");;
  174. oldOOS.close(); // also closes the Socket
  175. // And DON'T send the "Welcome" message to everyone for
  176. // this client because they never left the chat room...
  177. }
  178. // show this joining client any messages that have been saved
  179. // for them. (Re-joining clients will not have any because
  180. // they never left. They may have "missed" messages on their
  181. // previous-session screen at their previous location.)
  182. Vector<Object> savedMessageList = savedMessages.get(chatName);
  183. if (savedMessageList != null) // any messages?
  184. {
  185. while (!savedMessageList.isEmpty())
  186. {
  187. Object savedMessage = savedMessageList.remove(0);
  188. try {
  189. oos.writeObject(savedMessage);
  190. }
  191. catch(Exception e) // joiner has suddenly left!
  192. {
  193. savedMessageList.add(0, savedMessage);//put back
  194. break; // and stop showing
  195. }
  196. }
  197. saveSavedMessages();
  198. }
  199. } // bottom of try
  200. catch (Exception e)
  201. {
  202. System.out.println("Connection failure during join processing: " + e);
  203. if (s.isConnected())
  204. {
  205. try {s.close();} // hang up
  206. catch(IOException ioe){} // already hung up!
  207. }
  208. return; // kill this client's thread
  209. }
  210. // Show everyone who's in the chat room and who's not.
  211. String[] inChatNames = whosIn.keySet().toArray(new String[0]);
  212. String[] outChatNames = whosNotIn.toArray(new String[0]);
  213. Arrays.sort(inChatNames);
  214. Arrays.sort(outChatNames);
  215. sendToAllClients(inChatNames); // send who's-in to clients
  216. sendToAllClients(outChatNames); // send who's-not-in to clients
  217.  
  218. System.out.println("Currently in the chat room:");
  219. for (String name : inChatNames)
  220. System.out.println(name);
  221. System.out.println("Currently NOT in the chat room:");
  222. for (String name : outChatNames)
  223. System.out.println(name);
  224.  
  225. // 3. "SEND/RECEIVE processing" for this client.
  226. try {
  227. while (true) // loop forever
  228. {
  229. Object something = ois.readObject(); // wait for this client to say something
  230. if (something instanceof String)
  231. {
  232. String chatMessage = ((String) something).trim();
  233. System.out.println("Received '" + chatMessage + "' from " + chatName);
  234. sendToAllClients(chatName + " says: " + chatMessage);
  235. }
  236. else if (something instanceof String[]) // private or save
  237. {
  238. String[] recipients = (String[]) something;
  239. String firstRecipient = recipients[1];
  240. if (whosIn.containsKey(firstRecipient.toUpperCase()))
  241. sendPrivate(recipients, chatName);
  242. else saveMessage(recipients, chatName);
  243. }
  244. else if (something instanceof Object[]) {
  245. Object[] pictureAndRecipients = (Object[]) something;
  246. String firstRecipient = (String) pictureAndRecipients[1];
  247. if (whosIn.containsKey(firstRecipient.toUpperCase()))
  248. sendPrivatePicture(pictureAndRecipients, chatName);
  249. else savePicture(pictureAndRecipients, chatName);
  250. }
  251. else if (something instanceof ImageIcon) {
  252. sendToAllClients(something);
  253. }
  254. else
  255. {
  256. System.out.println("Received unexpected message type from "
  257. + chatName + ": " + something );
  258. }
  259. }
  260. }
  261.  
  262. // 4. "LEAVE processing" for this client.
  263. // The user closes the client window to leave the chat
  264. // room, terminating the client program and taking down
  265. // the connection. So the server will go to the catch
  266. // below from ois.readObject() above (which is then failing).
  267. catch (Exception e)
  268. {
  269. // Hello! Somehow, when the oos fails, we have to determine
  270. // whether Bubba has LEFT the chat room (in which case we want
  271. // to remove his oos) or has just REJOINED (in which case we DON'T
  272. // want to remove his now-new oos from the collection).
  273. ObjectOutputStream currentOOS = whosIn.get(chatName);
  274. if (currentOOS == oos) // same oos as when they joined
  275. {
  276. System.out.println(chatName + " is leaving.");
  277. whosIn.remove(chatName); // This is the ONLY place the client gets removed!
  278. whosNotIn.add(chatName); // And add them back to the not-in list.
  279. sendToAllClients("Goodbye to " + chatName
  280. + " who has just left the chat room!");
  281. // Show who's in the chat room and who's not.
  282. String[] inNames = whosIn.keySet().toArray(new String[0]);
  283. String[] outNames = whosNotIn.toArray(new String[0]);
  284. Arrays.sort(inNames);
  285. Arrays.sort(outNames);
  286. sendToAllClients(inNames); // send who's-in to clients
  287. sendToAllClients(outNames); // send who's-not-in to clients
  288.  
  289. System.out.println("Currently in the chat room:");
  290. for (String name : inNames)
  291. System.out.println(name);
  292. System.out.println("Currently NOT in the chat room:");
  293. for (String name : whosNotIn)
  294. System.out.println(name);
  295. }
  296. else // The retrieved oos is NOT the same, so DON'T DO ANYTHING.
  297. // This thread will die but Bubba's new client thread is active.
  298. {
  299. System.out.println(chatName + " is rejoining.");
  300. }
  301. }
  302. } // end of run(). client thread returns to the Thread
  303. // object and is terminated! (It's finished running.)
  304.  
  305. //=========================================================
  306. private synchronized void sendToAllClients(Object whatever)
  307. {
  308. System.out.println("Sending '" + whatever + "' to everyone.");
  309. // synchronization ensures that all clients will get all
  310. // messages in the same sequence. (Another client thread
  311. // cannot enter even if the thread currently in the
  312. // method is suspended by the O/S!)
  313. ObjectOutputStream[] oosList = whosIn.values().toArray(new ObjectOutputStream[0]);
  314.  
  315. for (ObjectOutputStream clientOOS : oosList)
  316. {
  317. try {clientOOS.writeObject(whatever);}
  318. catch (IOException e) {}
  319. }
  320. // Keep looping if a send to one of the clients fails!
  321. // No action need be taken here if the communications
  322. // writeObject() fails because we can count on that
  323. // client's thread, parked on a ois.readObject(),
  324. // also seeing the failure and removing the failed
  325. // oos from the collection!
  326. }
  327.  
  328. //=================================================================
  329. private void sendPrivate(String[] recipients, String sender)
  330. {
  331. String message = recipients[0];
  332. Vector<String> intendedRecipients = new Vector<String>();
  333. for (int n = 1; n < recipients.length; n++)
  334. intendedRecipients.add(recipients[n]);
  335. System.out.println("Received PRIVATE message '" + message
  336. + "' from " + sender
  337. + " to " + intendedRecipients);
  338. Vector<String> successfulRecipients = new Vector<String>();
  339. for (String chatName : intendedRecipients)
  340. {
  341. ObjectOutputStream oos = whosIn.get(chatName);
  342. if (oos == null) continue; // Bubba just left the chat room!
  343. try {
  344. oos.writeObject("PRIVATE from " + sender
  345. + " to " + intendedRecipients
  346. + " " + message);
  347. successfulRecipients.add(chatName);
  348. }
  349. catch(Exception e) {} // just continue to next recipient
  350. }
  351. // send confirmation to sender
  352. try {
  353. ObjectOutputStream oos = whosIn.get(sender);
  354. oos.writeObject("your PRIVATE message '" + message
  355. + "' was sent to " + successfulRecipients);
  356. }
  357. catch (Exception e)
  358. {
  359. System.out.println("Confirmation of send of private message '" + message
  360. + "could not be sent to " + sender);
  361. }
  362. }
  363.  
  364. //===================================================================
  365. private void saveMessage(String[] recipients, String sender)
  366. {
  367. String message = recipients[0];
  368. Vector<String> intendedRecipients = new Vector<String>();
  369. for (int n = 1; n < recipients.length; n++)
  370. intendedRecipients.add(recipients[n]);
  371. System.out.println("Received SAVE message '" + message
  372. + "' from " + sender
  373. + " to " + intendedRecipients);
  374. for (String chatName : intendedRecipients)
  375. {
  376. Vector<Object> messageList = savedMessages.get(chatName);
  377. if (messageList == null) // this client has no saved messages yet,
  378. { // so create a message Vector and add it.
  379. messageList = new Vector<Object>();
  380. savedMessages.put(chatName, messageList);
  381. }
  382. messageList.add(sender + " sent on " + new Date() + " " + message);
  383. }
  384. saveSavedMessages();
  385. // send confirmation message to sender
  386. ObjectOutputStream saverOOS = whosIn.get(sender);
  387. try {saverOOS.writeObject("Your message '" + message
  388. + "' was saved for " + intendedRecipients);}
  389. catch(Exception e) {}
  390. }
  391.  
  392. //=========================================================
  393. private synchronized void saveChatNames()
  394. {
  395. try {
  396. FileOutputStream fos = new FileOutputStream("clients.ser");
  397. ObjectOutputStream oos = new ObjectOutputStream(fos);
  398. oos.writeObject(clients);
  399. oos.close();
  400. }
  401. catch(Exception e)
  402. {
  403. System.out.println("clients.ser cannot be saved: " + e);
  404. }
  405. }
  406.  
  407. //=========================================================
  408. private synchronized void saveSavedMessages()
  409. {
  410. try {
  411. FileOutputStream fos = new FileOutputStream("Messages.ser");
  412. ObjectOutputStream oos = new ObjectOutputStream(fos);
  413. oos.writeObject(savedMessages);
  414. oos.close();
  415. }
  416. catch(Exception e)
  417. {
  418. System.out.println("Messages.ser cannot be saved: " + e);
  419. }
  420. }
  421.  
  422. private void sendPrivatePicture(Object[] pictureAndRecipients, String sender) {
  423. ImageIcon picture = (ImageIcon) pictureAndRecipients[0];
  424. Vector<String> recipients = new Vector<String>();
  425. for (int i = 1; i < pictureAndRecipients.length; i++)
  426. recipients.add((String) pictureAndRecipients[i]);
  427.  
  428. System.out.println("Received PRIVATE picture '" + picture
  429. + "' from " + sender
  430. + " to " + recipients);
  431.  
  432. Vector<String> successfulRecipients = new Vector<String>();
  433. for (String chatName : recipients) {
  434. ObjectOutputStream oos = whosIn.get(chatName);
  435. if (oos == null) continue; // Bubba just left the chat room!
  436. try {
  437. oos.writeObject(picture);
  438. successfulRecipients.add(chatName);
  439. } catch (Exception e) {
  440. } // just continue to next recipient
  441. }
  442.  
  443. // send confirmation to sender
  444. try {
  445. ObjectOutputStream oos = whosIn.get(sender);
  446. oos.writeObject("your PRIVATE picture '" + picture.getDescription() + "' was sent to " + successfulRecipients);
  447. } catch (Exception e) {
  448. System.out.println("Confirmation of send of private picture '" + picture
  449. + "could not be sent to " + sender);
  450. }
  451. }
  452.  
  453. private void savePicture(Object[] pictureAndRecipients, String sender) {
  454. ImageIcon picture = (ImageIcon) pictureAndRecipients[0];
  455. Vector<String> recipients = new Vector<String>();
  456. for (int n = 1; n < pictureAndRecipients.length; n++)
  457. recipients.add((String)pictureAndRecipients[n]);
  458.  
  459. System.out.println("Received SAVE message '" + picture
  460. + "' from " + sender
  461. + " to " + recipients);
  462.  
  463. for (String chatName : recipients) {
  464. Vector<Object> messageList = savedMessages.get(chatName);
  465. if (messageList == null) // this client has no saved messages yet,
  466. { // so create a message Vector and add it.
  467. messageList = new Vector<Object>();
  468. savedMessages.put(chatName, messageList);
  469. }
  470. messageList.add(picture);
  471. }
  472. saveSavedMessages();
  473. // send confirmation message to sender
  474. ObjectOutputStream saverOOS = whosIn.get(sender);
  475. try {
  476. saverOOS.writeObject("Your message '" + picture.getDescription()
  477. + "' was saved for " + recipients);
  478. } catch (Exception e) {
  479. }
  480.  
  481. }
  482. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement