From f538d0201efd92598ed5bd4cc73996639993acab Mon Sep 17 00:00:00 2001 From: josh Date: Tue, 25 Nov 2008 17:31:49 +0000 Subject: [PATCH] added ChatClient.java copied from lab3 git-svn-id: svn://anubis/gvsu@258 45c1a28c-8058-47b2-ae61-ca45b979098e --- cs656/lab4/ChatClient.java | 361 +++++++++++++++++++++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 cs656/lab4/ChatClient.java diff --git a/cs656/lab4/ChatClient.java b/cs656/lab4/ChatClient.java new file mode 100644 index 0000000..7e87f97 --- /dev/null +++ b/cs656/lab4/ChatClient.java @@ -0,0 +1,361 @@ + +/* Josh Holtrop + * 2008-12-04 + * CS656 + * Lab 4 + */ + +import java.net.InetAddress; +import java.net.MalformedURLException; + +import java.io.*; +import java.util.*; +import java.net.*; + +public class ChatClient +{ + private PresenceService myPServ; + private String myUserName; + private Thread myListenThread; + private ChatClientListener myListener; + private RegistrationInfo myRegistrationInfo; + + /** + * This class provides a thread to listen for incoming connections. + */ + private class ChatClientListener implements Runnable + { + ServerSocket mySocket; + + public ChatClientListener() + { + try + { + /* Just listen on any available TCP port */ + mySocket = new ServerSocket(0); + } + catch (Exception e) + { + System.err.println("Error creating listener thread!"); + e.printStackTrace(); + System.exit(-1); + } + } + + public int getPort() + { + return mySocket.getLocalPort(); + } + + public String getHost() + { + return mySocket.getInetAddress().getHostName(); + } + + /* called when the thread is first scheduled */ + public void run() + { + Socket s; + /* wait indefinitely for new connections */ + for (;;) + { + try + { + s = mySocket.accept(); + Thread cclt = new Thread(new ChatClientListenerThread(s)); + cclt.start(); + } + catch (Exception e) + { + } + } + } + + /** + * This class provides a listener for any connections that come in. + * All it does is print any received chat messages from the remote + * user to this user's screen. + */ + public class ChatClientListenerThread implements Runnable + { + Socket mySocket; + + public ChatClientListenerThread(Socket s) + { + mySocket = s; + } + + public void run() + { + try + { + InputStream is = mySocket.getInputStream(); + BufferedReader br = new BufferedReader(new InputStreamReader(is)); + while (!mySocket.isClosed()) + { + /* read and print a message from a peer */ + String in = br.readLine(); + if (in == null) + break; + System.out.println(in); + System.out.print("> "); + } + } + catch (Exception e) + { + return; + } + } + } + } + + /* construct the main ChatClient object */ + public ChatClient(PresenceService pserv, String userName) + { + myPServ = pserv; + myUserName = userName; + } + + public void run() + { + try + { + myListener = new ChatClientListener(); + myRegistrationInfo = + new RegistrationInfo(myUserName, + InetAddress.getLocalHost().getHostName(), + myListener.getPort(), + true); + if (!register()) + { + return; + } + } + catch (Exception e) + { + e.printStackTrace(); + return; + } + + /* Start a thread to listen for connections in */ + myListenThread = new Thread(myListener); + myListenThread.start(); + + mainloop(); + } + + /* call the register function in the presence service */ + private boolean register() + { + try { + myPServ.register(myRegistrationInfo); + } catch (Exception e) { + System.out.println("Exception caught when registering!"); + e.printStackTrace(); + return false; + } + return true; + } + + /* call the unregister function in the presence service */ + private boolean unregister() + { + try { + myPServ.unregister(myUserName); + } catch (Exception e) { + System.out.println("Exception caught when unregistering!"); + e.printStackTrace(); + return false; + } + return true; + } + + /* this is the main wait-for-input-and-respond loop */ + private void mainloop() + { + BufferedReader br = new BufferedReader( + new InputStreamReader(System.in)); + String line; + try + { + for (;;) + { + /* print a prompt */ + System.out.print("> "); + /* read a line of input */ + line = br.readLine(); + if (line == null) + break; + line = line.trim(); + if (line.equals("")) + continue; + /* break the input into the command word, and the rest */ + String command, rest; + int spaceIndex = line.indexOf(' '); + if (spaceIndex > 0) + { + command = line.substring(0, spaceIndex); + rest = line.substring(spaceIndex + 1); + rest = rest.trim(); + } + else + { + command = line; + rest = ""; + } + + if (command.equals("help") || command.equals("?")) + { + System.out.println("Commands:"); + System.out.println(" friends - view a list of all peers on the system"); + System.out.println(" talk {username} {message} - send message to username"); + System.out.println(" broadcast {message} - send message to every available user"); + System.out.println(" busy - set status to busy/away"); + System.out.println(" available - set status to busy/away"); + System.out.println(" exit - disconnect and exit program"); + } + else if (command.equals("talk")) + { + String user = ""; + int idx; + if ((idx = rest.indexOf(' ')) > 0) + { + user = rest.substring(0, idx); + RegistrationInfo ri = myPServ.lookup(user); + if (ri == null) + { + System.err.println("Could not find user \"" + user + "\"!"); + } + else + { + /* only send a message to available users */ + if (ri.getStatus()) + { + String message = rest.substring(idx + 1); + sendUserMessage(user, message); + } + else + { + System.out.println(user + " is busy!"); + } + } + } + else + { + System.out.println("Syntax: talk {user} {message}"); + } + } + else if (command.equals("busy")) + { + if (myRegistrationInfo.getStatus()) + { + myRegistrationInfo = new RegistrationInfo( + myRegistrationInfo.getUserName(), + myRegistrationInfo.getHost(), + myRegistrationInfo.getPort(), + false + ); + unregister(); + register(); + System.out.println("Status set to busy"); + } + } + else if (command.equals("available")) + { + if (!myRegistrationInfo.getStatus()) + { + myRegistrationInfo = new RegistrationInfo( + myRegistrationInfo.getUserName(), + myRegistrationInfo.getHost(), + myRegistrationInfo.getPort(), + true + ); + unregister(); + register(); + System.out.println("Status set to available"); + } + } + else if (command.equals("exit")) + { + myListenThread.interrupt(); + break; + } + else + { + System.out.println("Unrecognized Command! Type 'help' or '?' for help!"); + } + } + } + catch (Exception e) + { + e.printStackTrace(); + } + unregister(); + + try + { + myPServ.leave(); /* Leave the Chord network */ + } + catch (Exception e) + { + e.printStackTrace(); + } + System.exit(0); + } + + /* a useful subroutine to break out the task of sending a + * message to a particular user */ + private void sendUserMessage(String user, String message) + { + try + { + RegistrationInfo ri = myPServ.lookup(user); + if (ri != null) + { + Socket s = new Socket(InetAddress.getByName(ri.getHost()), + ri.getPort()); + OutputStream os = s.getOutputStream(); + message = myUserName + ": " + message; + os.write(message.getBytes()); + s.close(); + } + } + catch (Exception e) + { + System.err.println("Error sending message"); + e.printStackTrace(); + } + } + + public static void main(String[] args) + { + String user = "user"; + String host = "localhost"; + + for (int arg = 0; arg < args.length; arg++) + { + switch (arg) + { + case 0: + user = s.replace(' ', '_'); + break; + case 1: + host = s; + break; + default: + usage(); + } + } + + PresenceService pServ = new PresenceServiceImpl(); + + ChatClient chatClient = new ChatClient(pServ, user); + chatClient.run(); + } + + private static void usage() + { + System.err.println("Usage: java ChatClient [-master] {user} {host}"); + System.exit(42); + } +}