Loading src/main/java/ch15/SimpleChatClient.java +25 −30 Changes for src/main/java/ch15/SimpleChatClient.java: 25 added lines, 30 removed lines. Original line number Diff line number Diff line Loading @@ -4,19 +4,18 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.SocketChannel; import java.nio.charset.StandardCharsets; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class SimpleChatClient { public static void main(String[] args) throws IOException { SocketChannel socket = setUpNetworking(); Socket socket = setUpNetworking(); ClientUI clientUI = new ClientUI(); clientUI.go(socket); Loading @@ -27,17 +26,17 @@ public class SimpleChatClient { threadExecutor.shutdown(); } private static SocketChannel setUpNetworking() throws IOException { SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("localhost", 5000)); System.out.println("Networking established. Local address: " + socketChannel.getLocalAddress()); return socketChannel; private static Socket setUpNetworking() throws IOException { Socket socket = new Socket("127.0.0.1", 5000); System.out.println("networking established"); return socket; } } class ClientUI { private JTextArea incoming; public void go(SocketChannel socket) { public void go(Socket socket) { JFrame frame = new JFrame("Ludicrously Simple Chat Client"); JPanel mainPanel = new JPanel(); incoming = new JTextArea(15, 50); Loading @@ -64,19 +63,21 @@ class ClientUI { public static class SendButtonListener implements ActionListener { private final JTextField outgoing; private final SocketChannel channel; private final PrintWriter writer; public SendButtonListener(JTextField outgoingMessage, SocketChannel channel) { public SendButtonListener(JTextField outgoingMessage, Socket socket) { try { writer = new PrintWriter(socket.getOutputStream()); } catch (IOException e) { throw new RuntimeException(e); } outgoing = outgoingMessage; this.channel = channel; } public void actionPerformed(ActionEvent ev) { // pretty sure this is doing what I think it's doing byte[] message = outgoing.getText().getBytes(); ByteBuffer buffer = ByteBuffer.wrap(message); try { channel.write(buffer); writer.println(outgoing.getText()); writer.flush(); } catch (Exception ex) { ex.printStackTrace(); } Loading @@ -87,12 +88,12 @@ class ClientUI { } class IncomingReader implements Runnable { private final SocketChannel channel; private final BufferedReader reader; private final JTextArea incomingMessageArea; public IncomingReader(JTextArea incomingMessageArea, SocketChannel channel) { public IncomingReader(JTextArea incomingMessageArea, Socket socket) throws IOException { this.incomingMessageArea = incomingMessageArea; this.channel = channel; reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); } public void run() { Loading @@ -100,18 +101,12 @@ class IncomingReader implements Runnable { } private void processMessages() { ByteBuffer buffer = ByteBuffer.allocate(80); String message; try { while (channel.read(buffer) != -1) { buffer.flip(); CharBuffer message = StandardCharsets.UTF_8.decode(buffer); while ((message = reader.readLine()) != null) { System.out.println("read " + message); incomingMessageArea.append(message + "\n"); buffer.clear(); } channel.close(); System.out.println("Connection closed"); } // close while } catch (Exception ex) { ex.printStackTrace(); } Loading src/main/java/ch15/SimpleChatServer.java +29 −41 Changes for src/main/java/ch15/SimpleChatServer.java: 29 added lines, 41 removed lines. Original line number Diff line number Diff line package ch15; import java.io.BufferedReader; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.Iterator; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; Loading @@ -18,75 +20,61 @@ public class SimpleChatServer { public void go() { try { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.bind(new InetSocketAddress("localhost", 5000)); ServerSocket serverSock = new ServerSocket(5000); Broadcaster broadcaster = new Broadcaster(); while (serverSocketChannel.isOpen()) { SocketChannel clientSocket = serverSocketChannel.accept(); while (!serverSock.isClosed()) { Socket clientSocket = serverSock.accept(); broadcaster.addClient(clientSocket); executorService.execute(new ClientHandler(clientSocket, broadcaster)); System.out.println("got a connection"); } serverSocketChannel.close(); executorService.shutdown(); } catch (IOException ex) { } catch (Exception ex) { ex.printStackTrace(); } } } class ClientHandler implements Runnable { private final SocketChannel clientSocket; private final BufferedReader reader; private final Broadcaster broadcaster; public ClientHandler(SocketChannel clientSocket, Broadcaster broadcaster) { this.clientSocket = clientSocket; public ClientHandler(Socket clientSocket, Broadcaster broadcaster) throws IOException { this.broadcaster = broadcaster; } InputStreamReader isReader = new InputStreamReader(clientSocket.getInputStream()); reader = new BufferedReader(isReader); } // close constructor public void run() { ByteBuffer buffer = ByteBuffer.allocate(80); String message; try { while (clientSocket.read(buffer) != -1) { buffer.flip(); broadcaster.tellEveryone(buffer); buffer.clear(); } disconnectClient(); while ((message = reader.readLine()) != null) { System.out.println("read " + message); broadcaster.tellEveryone(message); } // close while } catch (Exception ex) { ex.printStackTrace(); } } private void disconnectClient() throws IOException { clientSocket.close(); System.out.println("Closed: " + clientSocket); broadcaster.remove(clientSocket); } } class Broadcaster { private final ArrayList<SocketChannel> clientOutputStreams = new ArrayList<>(); private final ArrayList<PrintWriter> clientOutputStreams = new ArrayList<>(); void addClient(SocketChannel clientSocket) { clientOutputStreams.add(clientSocket); void addClient(Socket clientSocket) throws IOException { clientOutputStreams.add(new PrintWriter(clientSocket.getOutputStream())); } public void tellEveryone(ByteBuffer buffer) { for (SocketChannel channel : clientOutputStreams) { public void tellEveryone(String message) { Iterator<PrintWriter> it = clientOutputStreams.iterator(); while (it.hasNext()) { try { while (buffer.hasRemaining()) { channel.write(buffer); } buffer.rewind(); PrintWriter writer = it.next(); writer.println(message); writer.flush(); } catch (Exception ex) { ex.printStackTrace(); } } } public void remove(SocketChannel clientSocket) { clientOutputStreams.remove(clientSocket); } } No newline at end of file Loading
src/main/java/ch15/SimpleChatClient.java +25 −30 Changes for src/main/java/ch15/SimpleChatClient.java: 25 added lines, 30 removed lines. Original line number Diff line number Diff line Loading @@ -4,19 +4,18 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.channels.SocketChannel; import java.nio.charset.StandardCharsets; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class SimpleChatClient { public static void main(String[] args) throws IOException { SocketChannel socket = setUpNetworking(); Socket socket = setUpNetworking(); ClientUI clientUI = new ClientUI(); clientUI.go(socket); Loading @@ -27,17 +26,17 @@ public class SimpleChatClient { threadExecutor.shutdown(); } private static SocketChannel setUpNetworking() throws IOException { SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("localhost", 5000)); System.out.println("Networking established. Local address: " + socketChannel.getLocalAddress()); return socketChannel; private static Socket setUpNetworking() throws IOException { Socket socket = new Socket("127.0.0.1", 5000); System.out.println("networking established"); return socket; } } class ClientUI { private JTextArea incoming; public void go(SocketChannel socket) { public void go(Socket socket) { JFrame frame = new JFrame("Ludicrously Simple Chat Client"); JPanel mainPanel = new JPanel(); incoming = new JTextArea(15, 50); Loading @@ -64,19 +63,21 @@ class ClientUI { public static class SendButtonListener implements ActionListener { private final JTextField outgoing; private final SocketChannel channel; private final PrintWriter writer; public SendButtonListener(JTextField outgoingMessage, SocketChannel channel) { public SendButtonListener(JTextField outgoingMessage, Socket socket) { try { writer = new PrintWriter(socket.getOutputStream()); } catch (IOException e) { throw new RuntimeException(e); } outgoing = outgoingMessage; this.channel = channel; } public void actionPerformed(ActionEvent ev) { // pretty sure this is doing what I think it's doing byte[] message = outgoing.getText().getBytes(); ByteBuffer buffer = ByteBuffer.wrap(message); try { channel.write(buffer); writer.println(outgoing.getText()); writer.flush(); } catch (Exception ex) { ex.printStackTrace(); } Loading @@ -87,12 +88,12 @@ class ClientUI { } class IncomingReader implements Runnable { private final SocketChannel channel; private final BufferedReader reader; private final JTextArea incomingMessageArea; public IncomingReader(JTextArea incomingMessageArea, SocketChannel channel) { public IncomingReader(JTextArea incomingMessageArea, Socket socket) throws IOException { this.incomingMessageArea = incomingMessageArea; this.channel = channel; reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); } public void run() { Loading @@ -100,18 +101,12 @@ class IncomingReader implements Runnable { } private void processMessages() { ByteBuffer buffer = ByteBuffer.allocate(80); String message; try { while (channel.read(buffer) != -1) { buffer.flip(); CharBuffer message = StandardCharsets.UTF_8.decode(buffer); while ((message = reader.readLine()) != null) { System.out.println("read " + message); incomingMessageArea.append(message + "\n"); buffer.clear(); } channel.close(); System.out.println("Connection closed"); } // close while } catch (Exception ex) { ex.printStackTrace(); } Loading
src/main/java/ch15/SimpleChatServer.java +29 −41 Changes for src/main/java/ch15/SimpleChatServer.java: 29 added lines, 41 removed lines. Original line number Diff line number Diff line package ch15; import java.io.BufferedReader; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.Iterator; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; Loading @@ -18,75 +20,61 @@ public class SimpleChatServer { public void go() { try { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.bind(new InetSocketAddress("localhost", 5000)); ServerSocket serverSock = new ServerSocket(5000); Broadcaster broadcaster = new Broadcaster(); while (serverSocketChannel.isOpen()) { SocketChannel clientSocket = serverSocketChannel.accept(); while (!serverSock.isClosed()) { Socket clientSocket = serverSock.accept(); broadcaster.addClient(clientSocket); executorService.execute(new ClientHandler(clientSocket, broadcaster)); System.out.println("got a connection"); } serverSocketChannel.close(); executorService.shutdown(); } catch (IOException ex) { } catch (Exception ex) { ex.printStackTrace(); } } } class ClientHandler implements Runnable { private final SocketChannel clientSocket; private final BufferedReader reader; private final Broadcaster broadcaster; public ClientHandler(SocketChannel clientSocket, Broadcaster broadcaster) { this.clientSocket = clientSocket; public ClientHandler(Socket clientSocket, Broadcaster broadcaster) throws IOException { this.broadcaster = broadcaster; } InputStreamReader isReader = new InputStreamReader(clientSocket.getInputStream()); reader = new BufferedReader(isReader); } // close constructor public void run() { ByteBuffer buffer = ByteBuffer.allocate(80); String message; try { while (clientSocket.read(buffer) != -1) { buffer.flip(); broadcaster.tellEveryone(buffer); buffer.clear(); } disconnectClient(); while ((message = reader.readLine()) != null) { System.out.println("read " + message); broadcaster.tellEveryone(message); } // close while } catch (Exception ex) { ex.printStackTrace(); } } private void disconnectClient() throws IOException { clientSocket.close(); System.out.println("Closed: " + clientSocket); broadcaster.remove(clientSocket); } } class Broadcaster { private final ArrayList<SocketChannel> clientOutputStreams = new ArrayList<>(); private final ArrayList<PrintWriter> clientOutputStreams = new ArrayList<>(); void addClient(SocketChannel clientSocket) { clientOutputStreams.add(clientSocket); void addClient(Socket clientSocket) throws IOException { clientOutputStreams.add(new PrintWriter(clientSocket.getOutputStream())); } public void tellEveryone(ByteBuffer buffer) { for (SocketChannel channel : clientOutputStreams) { public void tellEveryone(String message) { Iterator<PrintWriter> it = clientOutputStreams.iterator(); while (it.hasNext()) { try { while (buffer.hasRemaining()) { channel.write(buffer); } buffer.rewind(); PrintWriter writer = it.next(); writer.println(message); writer.flush(); } catch (Exception ex) { ex.printStackTrace(); } } } public void remove(SocketChannel clientSocket) { clientOutputStreams.remove(clientSocket); } } No newline at end of file