Server
package com.company; import java.io.*; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; public class Server { private ServerSocket server; private static final int SERVER_PROT = 1778; //存放所有客户端的输出流,用于广播消息 private List<PrintWriter> allOut; //启动 public static void main(String[] args) { try { Server server = new Server(); server.start(); } catch (Exception e) { e.printStackTrace(); } } //监听 public Server() throws Exception { try { server = new ServerSocket(SERVER_PROT); System.out.println("Server success"); allOut = new ArrayList<PrintWriter>(); } catch (Exception e) { //将来在这里可以记录日志 throw e; } } public void start() { try { int index = 0; //循环接受所有客户端的连接 while (true) { System.out.println(" Wait for a connection num=" + index++); Socket socket = server.accept(); System.out.println("ip为:" + socket.getInetAddress() + "已连接"); //启动一个线程来负责与该客户端交互 ClientHandler handler = new ClientHandler(socket); Thread t = new Thread(handler); t.start(); } } catch (Exception e) { e.printStackTrace(); } } private class ClientHandler implements Runnable { private Socket socket; private String host; /** * 该线程任务负责与指定客户端交互工作 */ public ClientHandler(Socket socket) { this.socket = socket; InetAddress address = socket.getInetAddress(); host = address.getHostAddress(); } public void run() { PrintWriter pw = null; try { InputStream in = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(in, "utf-8"); BufferedReader br = new BufferedReader(isr); OutputStream out = socket.getOutputStream(); OutputStreamWriter osw = new OutputStreamWriter(out, "utf-8"); pw = new PrintWriter(osw, true); synchronized (allOut) { allOut.add(pw); } //广播当前客户端上线 sendMessage(host + "上线了"); String msg = null; while ((msg = br.readLine()) != null) { sendMessage(host + "说:" + msg); } } catch (Exception e) { e.printStackTrace(); } finally { synchronized (allOut) { //将该客户端的输出流从共享集合中删除 allOut.remove(pw); sendMessage(host + "下线了"); try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 将消息广播给所有客户端 * * @param msg */ private void sendMessage(String msg) { synchronized (allOut) { for (PrintWriter o : allOut) { o.println(msg); } } } } }
Clent
package com.company; import java.io.*; import java.net.Socket; import java.util.Scanner; public class Client { private Socket socket; private static final String SERVER_ADDDR = "localhost"; private static final int SERVER_PORT = 1778; //启动 public static void main(String[] args) { Client client = null; try { client = new Client(); client.start(); } catch (Exception e) { //可以作为日志处理 System.out.println("connection is fail"); e.printStackTrace(); } } //连接服务器 public Client() throws Exception { try { socket = new Socket(SERVER_ADDDR, SERVER_PORT); System.out.println("connection is success"); } catch (Exception e) { throw e; } } //客户端启动方法 public void start() { OutputStream out = null; try { Scanner scanner = new Scanner(System.in); out = socket.getOutputStream(); OutputStreamWriter osw = new OutputStreamWriter(out, "utf-8"); PrintWriter pw = new PrintWriter(osw, true); //启动读取服务端发送过来消息的线程 ServerHandler handler = new ServerHandler(); Thread t = new Thread(handler); t.start(); String msg = null; while (true) { msg = scanner.nextLine(); pw.println(msg); } } catch (IOException e) { e.printStackTrace(); } finally { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 该线程专门用来接收服务端发送过来的 * 消息并输出到控制台 * */ private class ServerHandler implements Runnable { public void run() { InputStream in = null; try { in = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(in, "utf-8"); BufferedReader br = new BufferedReader(isr); String msg = null; while ((msg = br.readLine()) != null) { System.out.println(msg); } } catch (IOException e) { e.printStackTrace(); } finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } } }