From 844606bf229628478d6f7e30d1483f492c93f7b2 Mon Sep 17 00:00:00 2001 From: Dan Bardin Date: Tue, 7 Apr 2015 13:57:11 -0500 Subject: [PATCH 1/2] Initial commit of client/server framework Created four files: Two for server, two for client. Allows for many-user connection to single server to send and recieve messages by other active users. --- ClientServerFramework/Client.java | 120 ++++++++++++++++ ClientServerFramework/ClientThread.java | 61 ++++++++ ClientServerFramework/Server.java | 184 ++++++++++++++++++++++++ ClientServerFramework/ServerThread.java | 107 ++++++++++++++ 4 files changed, 472 insertions(+) create mode 100644 ClientServerFramework/Client.java create mode 100644 ClientServerFramework/ClientThread.java create mode 100644 ClientServerFramework/Server.java create mode 100644 ClientServerFramework/ServerThread.java diff --git a/ClientServerFramework/Client.java b/ClientServerFramework/Client.java new file mode 100644 index 0000000..8a85eff --- /dev/null +++ b/ClientServerFramework/Client.java @@ -0,0 +1,120 @@ +/** + * Created by danielbardin on 4/6/15. + */ + +import java.net.*; +import java.io.*; + +public class Client implements Runnable +{ + private Socket socket = null; + private Thread thread = null; + private BufferedReader consoleBuffer = null; + private DataOutputStream outputStream = null; + private ClientThread client = null; + + + /* + Create client object + */ + public Client(String serverName, int serverPort) + { + System.out.println("Connecting to server host: " + serverName + " at port: " + serverPort); + try + { + socket = new Socket(serverName, serverPort); + System.out.println("Connected: " + socket); + start(); + } + catch (UnknownHostException e) + { + System.out.println("Host unknown: " + e.getMessage()); + } + catch (IOException e) + { + System.out.println("Unexpected exception: " + e.getMessage()); + } + } + + /* + create a new client thread + */ + public void run() + { + while (thread != null) { + try { + outputStream.writeUTF(consoleBuffer.readLine()); + outputStream.flush(); + } catch (IOException e) { + System.out.println("Sending error: " + e.getMessage()); + stop(); + } + } + } + + + /* + method for a client to send a message + */ + public void sendMessage(String message) + { + if (message.equals("logmeout")) { + System.out.println("logmeout recognized. Press RETURN to exit."); + stop(); + } + else + System.out.println(message); + } + + /* + initialize a client thread + */ + public void start() throws IOException + { + consoleBuffer = new BufferedReader(new InputStreamReader(System.in)); + outputStream = new DataOutputStream(socket.getOutputStream()); + + if (thread == null) + { + client = new ClientThread(this, socket); + thread = new Thread(this); + thread.start(); + } + } + + /* + Log out a client thread, shut down connections, close streams + */ + public void stop() + { + if (thread != null) { + thread.interrupt(); + thread = null; + } + + try + { + if (consoleBuffer != null) + consoleBuffer.close(); + if (outputStream != null) + outputStream.close(); + if (socket != null) + socket.close(); + } + catch (IOException e) + { + System.out.println("Error closing client process. Error message: " + e); + } + client.close(); + client.interrupt(); + } + + public static void main(String args[]) + { + Client client = null; + if (args.length != 2) + System.out.println("Usage: java Client host port"); + else + client = new Client(args[0], Integer.parseInt(args[1])); + } +} diff --git a/ClientServerFramework/ClientThread.java b/ClientServerFramework/ClientThread.java new file mode 100644 index 0000000..07e5b26 --- /dev/null +++ b/ClientServerFramework/ClientThread.java @@ -0,0 +1,61 @@ +/** + * Created by danielbardin on 4/6/15. + */ + +import java.net.*; +import java.io.*; + +public class ClientThread extends Thread +{ + + private Socket socket = null; + private Client client = null; + private BufferedReader inputBuffer = null; + + public ClientThread(Client client, Socket socket) + { + this.client = client; + this.socket = socket; + open(); + start(); + } + + /* + Connects this client via socket and creates a input reader + */ + public void open() + { + try { + inputBuffer = new BufferedReader(new InputStreamReader(socket.getInputStream())); + } catch (IOException e) { + System.out.println("Error getting input stream: " + e); + client.stop(); + } + } + + public void close() + { + try { + if (inputBuffer != null) + inputBuffer.close(); + } + catch (IOException e) { + System.out.println("Error closing input stream: " + e); + } + } + + /* + Listener for client in infinite loop. Terminates when "logmeoff" read by server during message send + */ + public void run() + { + while (true) { + try { + client.sendMessage(inputBuffer.readLine()); + } catch (IOException e) { + System.out.println("Listening error: " + e.getMessage()); + client.stop(); + } + } + } +} diff --git a/ClientServerFramework/Server.java b/ClientServerFramework/Server.java new file mode 100644 index 0000000..c8dab1e --- /dev/null +++ b/ClientServerFramework/Server.java @@ -0,0 +1,184 @@ +/** + * Created by danielbardin on 4/6/15. + */ + +import java.net.*; +import java.io.*; +import java.util.ArrayList; + +/* + Class to implement the server-side functionality and main method for a chat service + */ +public class Server implements Runnable +{ + // ArrayList of client/thread objects + private ArrayList clients = new ArrayList(); + + // This server's socket + private ServerSocket server = null; + + // This server's main thread; + private Thread thread = null; + + // How many clients are on this channel + private int numClients = 0; + + // Maximum number of clients allowed on this server + private static final int MAX_CLIENTS = 25; + + + /* + Constructor + */ + public Server(int port) + { + try { + // Prompt user of port connection attempt + System.out.println("Trying to connect to port: " + port); + + // make the connection to the port on our server + server = new ServerSocket(port); + + // prompt user of connection success. + System.out.println("Connection successful."); + + // start up the client + start(); + + } catch (IOException e) { + // Problem connecting + System.out.println("Could not attach to port: " + port + " The error was: " + e.getMessage()); + } + } + + /* + Start up + */ + public void run() + { + while (thread != null) { + try { + System.out.println("Waiting for first client connection. "); + addClient(server.accept()); + } catch (IOException e) { + System.out.println("Server run() error: " + e); + } + } + } + + + /* + Activate client thread + */ + public void start() + { + if (thread == null) { + thread = new Thread(this); + thread.start(); + } + } + +// /* +// Terminate client thread +// */ +// public void interrupt() +// { +// if (!thread.isInterrupted()) { +// thread.interrupt(); +// thread = null; +// } +// } + + /* + Find the client attempting to connect + */ + private int findClient(int id) + { + for (int i = 0; i < numClients; i++) { + if (clients.get(i).getId() == id) + return i; + } + return -1; + } + + + /* + Post a message to all users in this channel(i.e., host@port) from this id + */ + public synchronized void sendMessage(int id, String message) + { + // logmeout phrase will exit a person from the channel + if (message.equals("logmeout")) { + logoff(id); + } + else { + // Loops the clients array and posts the message to each. + for (ServerThread st : clients) { + st.sendMessage(id + ": " + message); + } + } + } + + + /* + Remove a user from the active roster and close their connection + */ + public synchronized void logoff(int id) + { + int clientsArrPos = findClient(id); + + if (clients.get(clientsArrPos).getId() == id) { + + numClients--; + + try { + clients.get(clientsArrPos).close(); + clients.remove(clientsArrPos); + } + catch (IOException e) { + System.out.println("Failed to log client off. Error message: " + e); + } + } + } + + + /* + Add a client thread to the server + */ + private void addClient(Socket socket) + { + // make sure clients is < 25 connections + if (numClients < MAX_CLIENTS) { + System.out.println("Client socket connection valid: " + socket); + + // Add a client thread to clients roster of active users. + clients.add(new ServerThread(this, socket)); + + try { + clients.get(numClients).open(); + clients.get(numClients).start(); + numClients++; + } + catch (IOException e) { + System.out.println("Error opening client thread: " + e); + clients.remove(clients.size()-1); + } + } + else { + System.out.println("Sorry, this channel is full."); + } + } + + /* + MAIN METHOD + */ + public static void main(String args[]) + { + Server server = null; + + if (args.length != 1) + System.out.println("Usage: java Server port"); + else + server = new Server(Integer.parseInt(args[0])); + } +} diff --git a/ClientServerFramework/ServerThread.java b/ClientServerFramework/ServerThread.java new file mode 100644 index 0000000..51c3ee0 --- /dev/null +++ b/ClientServerFramework/ServerThread.java @@ -0,0 +1,107 @@ +/** + * Created by danielbardin on 4/6/15. + */ + +import java.net.*; +import java.io.*; + + +/* + Class for a server-side thread interface + */ +public class ServerThread extends Thread +{ + private Server server = null; + private Socket socket = null; + private int id = -1; + private BufferedReader inputBuffer = null; + private DataOutputStream outputStream = null; + + + /* + Constructor for the master server thread, calls the Thread superclass library , then initializes. + + A client thread can interface with the server, and other clients through this class. + */ + public ServerThread(Server server, Socket socket) + { + super(); + this.server = server; + this.socket = socket; + id = socket.getPort(); + } + + /* + Method for server thread to send message + */ + public void sendMessage(String message) + { + try + { + outputStream.writeUTF(message); + outputStream.flush(); + } + catch (IOException e) + { + System.out.println("Error sending message from user: " + id + "Error is: " + e.getMessage()); + + // If there is an send error, likely the socket failed, + // remove the user and kill their thread. + server.logoff(id); + interrupt(); + } + } + + /* + getter for thread ID + */ + public long getId() + { + return id; + } + + /* + Infinite "listener." Will keep listening and sending messages + */ + public void run() + { + System.out.println("ServerThread: " + id + " is running."); + + while (true) { + try + { + server.sendMessage(id, inputBuffer.readLine()); + } + catch (IOException e) + { + System.out.println(id + " Error reading: " + e.getMessage()); + server.logoff(id); + interrupt(); + } + } + } + + /* + Initialize and open the input buffer and output stream(s) + */ + public void open() throws IOException + { + inputBuffer = new BufferedReader(new InputStreamReader(socket.getInputStream())); + outputStream = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); + } + + /* + Close out socket, input & output + */ + public void close() throws IOException + { + if (socket != null) + socket.close(); + if (inputBuffer != null) + inputBuffer.close(); + if (outputStream != null) + outputStream.close(); + } + + +} From 46b999bc501c79cf62338584e1e36b2c80ba3b0b Mon Sep 17 00:00:00 2001 From: Dan Bardin Date: Tue, 7 Apr 2015 14:34:33 -0500 Subject: [PATCH 2/2] Rollback to code with deprecated warning For now, ignore the deprecated warning. --- ClientServerFramework/Client.class | Bin 0 -> 3102 bytes ClientServerFramework/Client.java | 10 +++++----- ClientServerFramework/ClientThread.class | Bin 0 -> 1665 bytes ClientServerFramework/ClientThread.java | 11 ++++++----- ClientServerFramework/ServerThread.java | 10 +++++----- 5 files changed, 16 insertions(+), 15 deletions(-) create mode 100644 ClientServerFramework/Client.class create mode 100644 ClientServerFramework/ClientThread.class diff --git a/ClientServerFramework/Client.class b/ClientServerFramework/Client.class new file mode 100644 index 0000000000000000000000000000000000000000..6336b68a257ca6405acb5c7bb15f865e3c8b2893 GIT binary patch literal 3102 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 literal 0 HcmV?d00001 diff --git a/ClientServerFramework/ClientThread.java b/ClientServerFramework/ClientThread.java index 07e5b26..98278f9 100644 --- a/ClientServerFramework/ClientThread.java +++ b/ClientServerFramework/ClientThread.java @@ -10,7 +10,8 @@ public class ClientThread extends Thread private Socket socket = null; private Client client = null; - private BufferedReader inputBuffer = null; + //private BufferedReader inputBuffer = null; + private DataInputStream inputStream = null; public ClientThread(Client client, Socket socket) { @@ -26,7 +27,7 @@ public ClientThread(Client client, Socket socket) public void open() { try { - inputBuffer = new BufferedReader(new InputStreamReader(socket.getInputStream())); + inputStream = new DataInputStream(socket.getInputStream()); } catch (IOException e) { System.out.println("Error getting input stream: " + e); client.stop(); @@ -36,8 +37,8 @@ public void open() public void close() { try { - if (inputBuffer != null) - inputBuffer.close(); + if (inputStream != null) + inputStream.close(); } catch (IOException e) { System.out.println("Error closing input stream: " + e); @@ -51,7 +52,7 @@ public void run() { while (true) { try { - client.sendMessage(inputBuffer.readLine()); + client.sendMessage(inputStream.readUTF()); } catch (IOException e) { System.out.println("Listening error: " + e.getMessage()); client.stop(); diff --git a/ClientServerFramework/ServerThread.java b/ClientServerFramework/ServerThread.java index 51c3ee0..cdfa5e4 100644 --- a/ClientServerFramework/ServerThread.java +++ b/ClientServerFramework/ServerThread.java @@ -14,7 +14,7 @@ public class ServerThread extends Thread private Server server = null; private Socket socket = null; private int id = -1; - private BufferedReader inputBuffer = null; + private DataInputStream inputStream = null; private DataOutputStream outputStream = null; @@ -70,7 +70,7 @@ public void run() while (true) { try { - server.sendMessage(id, inputBuffer.readLine()); + server.sendMessage(id, inputStream.readUTF()); } catch (IOException e) { @@ -86,7 +86,7 @@ Initialize and open the input buffer and output stream(s) */ public void open() throws IOException { - inputBuffer = new BufferedReader(new InputStreamReader(socket.getInputStream())); + inputStream = new DataInputStream(new BufferedInputStream(socket.getInputStream())); outputStream = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); } @@ -97,8 +97,8 @@ public void close() throws IOException { if (socket != null) socket.close(); - if (inputBuffer != null) - inputBuffer.close(); + if (inputStream != null) + inputStream.close(); if (outputStream != null) outputStream.close(); }