Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import javax.swing.*;
- import java.io.*;
- import java.net.*;
- import java.util.*;
- import java.util.concurrent.ConcurrentHashMap;
- public class PictureChatServer implements Runnable
- {
- public static void main(String[] args) throws Exception
- {
- if (args.length > 0)
- System.out.println("Command line parameters are not accepted by ChatServer.");
- new PictureChatServer();
- }
- private ServerSocket ss;
- private int serverPort = 6666;
- // key will be the chat name of user in the chat room.
- // the associated String will be the password for that chatName.
- private ConcurrentHashMap<String,String> clients =
- new ConcurrentHashMap<String,String>();
- private ConcurrentHashMap<String,ObjectOutputStream> whosIn =
- new ConcurrentHashMap<String,ObjectOutputStream>();
- private Vector<String> whosNotIn;
- private ConcurrentHashMap<String, Vector<Object>> savedMessages =
- new ConcurrentHashMap<String, Vector<Object>>();
- //========================================================
- public PictureChatServer() throws Exception // CONSTRUCTOR
- {
- // System.out.println("***********************************************************");
- System.out.println("ECE 309 Lab6 PrivateChatServer\nSpring 2017\nAuthor: Nivesh Varma\n");
- // System.out.println("***********************************************************");
- ss = new ServerSocket(serverPort);
- // restore the SavedMessages collection from disk.
- try {
- FileInputStream fis = new FileInputStream("Messages.ser");
- ObjectInputStream ois = new ObjectInputStream(fis);
- savedMessages = (ConcurrentHashMap<String,Vector<Object>>) ois.readObject();
- ois.close();
- }
- catch(FileNotFoundException fnfe)
- {
- System.out.println("Messages.ser is not found, so an empty collection will be used.");
- }
- System.out.println("Messages previously saved for clients are:");
- System.out.println(savedMessages);
- // restore the clients collection from disk that has the passwords.
- try {
- FileInputStream fis = new FileInputStream("clients.ser");
- ObjectInputStream ois = new ObjectInputStream(fis);
- clients = (ConcurrentHashMap<String,String>) ois.readObject();
- ois.close();
- }
- catch(FileNotFoundException fnfe)
- {
- System.out.println("clients.ser is not found, so an empty collection will be used.");
- }
- System.out.println("Previously in the chat room: ");
- System.out.println(clients);
- // all previous clients are
- whosNotIn = new Vector(clients.keySet());// who is not in the chat room
- // when the server comes up.
- System.out.println("ChatServer is up at "
- + InetAddress.getLocalHost().getHostAddress()
- + " on port " + ss.getLocalPort());
- new Thread(this).start(); // create 1st client Thread
- } // to execute run() method.
- //=========================================================
- /** Each client goes through 4 stages:
- * 1. connection processing
- * 2. join processing
- * 3. send/receive processing
- * 4. leave processing
- * (See these sections in the run() method below.)
- */
- public void run()//each client application thread enters here!
- {
- Socket s = null;
- ObjectInputStream ois = null;
- ObjectOutputStream oos = null;
- String firstMessage = null;
- String chatName = null;
- String enteredPassword = null;
- String clientAddress = null;
- try {
- s = ss.accept(); // wait for next client to connect
- ois = new ObjectInputStream(s.getInputStream());
- firstMessage = (String) ois.readObject();
- oos = new ObjectOutputStream(s.getOutputStream());
- }
- catch(Exception e) // client protocol is not oos
- { // or firstMessage is not a String
- if (s != null)
- clientAddress = s.getInetAddress().getHostAddress();
- System.out.println("Connect/join exception from " + clientAddress);
- return; // terminate this client thread
- }
- finally
- {
- new Thread(this).start();
- }
- // If we are still running here s, ois, oos, and firstMessage are all good!
- // Whether catch was entered or NOT, a new thread has been created and has entered run().
- try {
- System.out.println("First message received: " + firstMessage);
- int spaceOffset = firstMessage.indexOf(" ");
- if (spaceOffset < 0)
- {
- oos.writeObject("Invalid format. " // 1) send err msg
- + "Are you calling the right address and port?");
- oos.close(); // 2) hang up
- System.out.println("Invalid 1st message received (no space separator): " + firstMessage);
- return; // 3) kill this client thread.
- }
- chatName = firstMessage.substring(0,spaceOffset).toUpperCase();
- enteredPassword = firstMessage.substring(spaceOffset).trim();
- if (enteredPassword.contains(" "))
- {
- oos.writeObject("Invalid format. " // 1) send err msg
- + "Are you calling the right address and port?");
- oos.close(); // 2) hang up
- System.out.println("Invalid 1st message received (space in name or pw): " + firstMessage);
- return; // 3) kill this client thread.
- }
- if (clients.containsKey(chatName)) // this name already in?
- {
- String storedPassword = clients.get(chatName);
- if (!enteredPassword.equals(storedPassword))
- {
- oos.writeObject("Your entered password " + enteredPassword + " is not the same as the password stored for chat name " + chatName);
- oos.close(); // hang up.
- System.out.println("Invalid password: " + enteredPassword + " instead of " + storedPassword);
- return; // and kill this client thread
- }
- }
- else // this chatName has never joined
- { // so join them!
- clients.put(chatName, enteredPassword);
- saveChatNames();
- }
- // 2. "JOIN processing" for this client
- oos.writeObject("Welcome to the chat room " + chatName + "!"); // confirm to client that they are in!
- // note that if write above fails, put & send below doesn't happen...
- // Is this a RECONNECT? (a re-join from a new location of
- // someone that was ALREADY IN the char room?
- if (!whosIn.containsKey(chatName)) // not already in
- {
- sendToAllClients("Welcome to " + chatName + " who has just joined the chat room!");
- whosIn.put(chatName,oos); // add new-join client to whosIn collection
- whosNotIn.remove(chatName); // and remove from WhosNotIn list.
- System.out.println(chatName + " is joining");
- }
- else // THIS CLIENT IS ALREADY IN THE CHAT ROOM!
- // e.g. This person left work without leaving the chat
- // room and is now signing on from home. We know it is
- // them because they passed the password test above.
- // So we are going to SHUT DOWN their old session, and
- // then REPLACE their old oos in the clients collection
- // with their new oos.
- {
- ObjectOutputStream oldOOS = whosIn.get(chatName);
- whosIn.replace(chatName, oos); // don't delay!
- oldOOS.writeObject("Session shut down due to rejoin from new location.");;
- oldOOS.close(); // also closes the Socket
- // And DON'T send the "Welcome" message to everyone for
- // this client because they never left the chat room...
- }
- // show this joining client any messages that have been saved
- // for them. (Re-joining clients will not have any because
- // they never left. They may have "missed" messages on their
- // previous-session screen at their previous location.)
- Vector<Object> savedMessageList = savedMessages.get(chatName);
- if (savedMessageList != null) // any messages?
- {
- while (!savedMessageList.isEmpty())
- {
- Object savedMessage = savedMessageList.remove(0);
- try {
- oos.writeObject(savedMessage);
- }
- catch(Exception e) // joiner has suddenly left!
- {
- savedMessageList.add(0, savedMessage);//put back
- break; // and stop showing
- }
- }
- saveSavedMessages();
- }
- } // bottom of try
- catch (Exception e)
- {
- System.out.println("Connection failure during join processing: " + e);
- if (s.isConnected())
- {
- try {s.close();} // hang up
- catch(IOException ioe){} // already hung up!
- }
- return; // kill this client's thread
- }
- // Show everyone who's in the chat room and who's not.
- String[] inChatNames = whosIn.keySet().toArray(new String[0]);
- String[] outChatNames = whosNotIn.toArray(new String[0]);
- Arrays.sort(inChatNames);
- Arrays.sort(outChatNames);
- sendToAllClients(inChatNames); // send who's-in to clients
- sendToAllClients(outChatNames); // send who's-not-in to clients
- System.out.println("Currently in the chat room:");
- for (String name : inChatNames)
- System.out.println(name);
- System.out.println("Currently NOT in the chat room:");
- for (String name : outChatNames)
- System.out.println(name);
- // 3. "SEND/RECEIVE processing" for this client.
- try {
- while (true) // loop forever
- {
- Object something = ois.readObject(); // wait for this client to say something
- if (something instanceof String)
- {
- String chatMessage = ((String) something).trim();
- System.out.println("Received '" + chatMessage + "' from " + chatName);
- sendToAllClients(chatName + " says: " + chatMessage);
- }
- else if (something instanceof String[]) // private or save
- {
- String[] recipients = (String[]) something;
- String firstRecipient = recipients[1];
- if (whosIn.containsKey(firstRecipient.toUpperCase()))
- sendPrivate(recipients, chatName);
- else saveMessage(recipients, chatName);
- }
- else if (something instanceof Object[]) {
- Object[] pictureAndRecipients = (Object[]) something;
- String firstRecipient = (String) pictureAndRecipients[1];
- if (whosIn.containsKey(firstRecipient.toUpperCase()))
- sendPrivatePicture(pictureAndRecipients, chatName);
- else savePicture(pictureAndRecipients, chatName);
- }
- else if (something instanceof ImageIcon) {
- sendToAllClients(something);
- }
- else
- {
- System.out.println("Received unexpected message type from "
- + chatName + ": " + something );
- }
- }
- }
- // 4. "LEAVE processing" for this client.
- // The user closes the client window to leave the chat
- // room, terminating the client program and taking down
- // the connection. So the server will go to the catch
- // below from ois.readObject() above (which is then failing).
- catch (Exception e)
- {
- // Hello! Somehow, when the oos fails, we have to determine
- // whether Bubba has LEFT the chat room (in which case we want
- // to remove his oos) or has just REJOINED (in which case we DON'T
- // want to remove his now-new oos from the collection).
- ObjectOutputStream currentOOS = whosIn.get(chatName);
- if (currentOOS == oos) // same oos as when they joined
- {
- System.out.println(chatName + " is leaving.");
- whosIn.remove(chatName); // This is the ONLY place the client gets removed!
- whosNotIn.add(chatName); // And add them back to the not-in list.
- sendToAllClients("Goodbye to " + chatName
- + " who has just left the chat room!");
- // Show who's in the chat room and who's not.
- String[] inNames = whosIn.keySet().toArray(new String[0]);
- String[] outNames = whosNotIn.toArray(new String[0]);
- Arrays.sort(inNames);
- Arrays.sort(outNames);
- sendToAllClients(inNames); // send who's-in to clients
- sendToAllClients(outNames); // send who's-not-in to clients
- System.out.println("Currently in the chat room:");
- for (String name : inNames)
- System.out.println(name);
- System.out.println("Currently NOT in the chat room:");
- for (String name : whosNotIn)
- System.out.println(name);
- }
- else // The retrieved oos is NOT the same, so DON'T DO ANYTHING.
- // This thread will die but Bubba's new client thread is active.
- {
- System.out.println(chatName + " is rejoining.");
- }
- }
- } // end of run(). client thread returns to the Thread
- // object and is terminated! (It's finished running.)
- //=========================================================
- private synchronized void sendToAllClients(Object whatever)
- {
- System.out.println("Sending '" + whatever + "' to everyone.");
- // synchronization ensures that all clients will get all
- // messages in the same sequence. (Another client thread
- // cannot enter even if the thread currently in the
- // method is suspended by the O/S!)
- ObjectOutputStream[] oosList = whosIn.values().toArray(new ObjectOutputStream[0]);
- for (ObjectOutputStream clientOOS : oosList)
- {
- try {clientOOS.writeObject(whatever);}
- catch (IOException e) {}
- }
- // Keep looping if a send to one of the clients fails!
- // No action need be taken here if the communications
- // writeObject() fails because we can count on that
- // client's thread, parked on a ois.readObject(),
- // also seeing the failure and removing the failed
- // oos from the collection!
- }
- //=================================================================
- private void sendPrivate(String[] recipients, String sender)
- {
- String message = recipients[0];
- Vector<String> intendedRecipients = new Vector<String>();
- for (int n = 1; n < recipients.length; n++)
- intendedRecipients.add(recipients[n]);
- System.out.println("Received PRIVATE message '" + message
- + "' from " + sender
- + " to " + intendedRecipients);
- Vector<String> successfulRecipients = new Vector<String>();
- for (String chatName : intendedRecipients)
- {
- ObjectOutputStream oos = whosIn.get(chatName);
- if (oos == null) continue; // Bubba just left the chat room!
- try {
- oos.writeObject("PRIVATE from " + sender
- + " to " + intendedRecipients
- + " " + message);
- successfulRecipients.add(chatName);
- }
- catch(Exception e) {} // just continue to next recipient
- }
- // send confirmation to sender
- try {
- ObjectOutputStream oos = whosIn.get(sender);
- oos.writeObject("your PRIVATE message '" + message
- + "' was sent to " + successfulRecipients);
- }
- catch (Exception e)
- {
- System.out.println("Confirmation of send of private message '" + message
- + "could not be sent to " + sender);
- }
- }
- //===================================================================
- private void saveMessage(String[] recipients, String sender)
- {
- String message = recipients[0];
- Vector<String> intendedRecipients = new Vector<String>();
- for (int n = 1; n < recipients.length; n++)
- intendedRecipients.add(recipients[n]);
- System.out.println("Received SAVE message '" + message
- + "' from " + sender
- + " to " + intendedRecipients);
- for (String chatName : intendedRecipients)
- {
- Vector<Object> messageList = savedMessages.get(chatName);
- if (messageList == null) // this client has no saved messages yet,
- { // so create a message Vector and add it.
- messageList = new Vector<Object>();
- savedMessages.put(chatName, messageList);
- }
- messageList.add(sender + " sent on " + new Date() + " " + message);
- }
- saveSavedMessages();
- // send confirmation message to sender
- ObjectOutputStream saverOOS = whosIn.get(sender);
- try {saverOOS.writeObject("Your message '" + message
- + "' was saved for " + intendedRecipients);}
- catch(Exception e) {}
- }
- //=========================================================
- private synchronized void saveChatNames()
- {
- try {
- FileOutputStream fos = new FileOutputStream("clients.ser");
- ObjectOutputStream oos = new ObjectOutputStream(fos);
- oos.writeObject(clients);
- oos.close();
- }
- catch(Exception e)
- {
- System.out.println("clients.ser cannot be saved: " + e);
- }
- }
- //=========================================================
- private synchronized void saveSavedMessages()
- {
- try {
- FileOutputStream fos = new FileOutputStream("Messages.ser");
- ObjectOutputStream oos = new ObjectOutputStream(fos);
- oos.writeObject(savedMessages);
- oos.close();
- }
- catch(Exception e)
- {
- System.out.println("Messages.ser cannot be saved: " + e);
- }
- }
- private void sendPrivatePicture(Object[] pictureAndRecipients, String sender) {
- ImageIcon picture = (ImageIcon) pictureAndRecipients[0];
- Vector<String> recipients = new Vector<String>();
- for (int i = 1; i < pictureAndRecipients.length; i++)
- recipients.add((String) pictureAndRecipients[i]);
- System.out.println("Received PRIVATE picture '" + picture
- + "' from " + sender
- + " to " + recipients);
- Vector<String> successfulRecipients = new Vector<String>();
- for (String chatName : recipients) {
- ObjectOutputStream oos = whosIn.get(chatName);
- if (oos == null) continue; // Bubba just left the chat room!
- try {
- oos.writeObject(picture);
- successfulRecipients.add(chatName);
- } catch (Exception e) {
- } // just continue to next recipient
- }
- // send confirmation to sender
- try {
- ObjectOutputStream oos = whosIn.get(sender);
- oos.writeObject("your PRIVATE picture '" + picture.getDescription() + "' was sent to " + successfulRecipients);
- } catch (Exception e) {
- System.out.println("Confirmation of send of private picture '" + picture
- + "could not be sent to " + sender);
- }
- }
- private void savePicture(Object[] pictureAndRecipients, String sender) {
- ImageIcon picture = (ImageIcon) pictureAndRecipients[0];
- Vector<String> recipients = new Vector<String>();
- for (int n = 1; n < pictureAndRecipients.length; n++)
- recipients.add((String)pictureAndRecipients[n]);
- System.out.println("Received SAVE message '" + picture
- + "' from " + sender
- + " to " + recipients);
- for (String chatName : recipients) {
- Vector<Object> messageList = savedMessages.get(chatName);
- if (messageList == null) // this client has no saved messages yet,
- { // so create a message Vector and add it.
- messageList = new Vector<Object>();
- savedMessages.put(chatName, messageList);
- }
- messageList.add(picture);
- }
- saveSavedMessages();
- // send confirmation message to sender
- ObjectOutputStream saverOOS = whosIn.get(sender);
- try {
- saverOOS.writeObject("Your message '" + picture.getDescription()
- + "' was saved for " + recipients);
- } catch (Exception e) {
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement