Java IO和网络编程(续)
作者:陆金龙
发表时间:2024-02-24 05:49
关键词:
17.3 基于TCP协议的网络编程
public class MyServer { // 定义保存所有Socket的ArrayList,并将其包装为线程安全的 public static List<Socket> socketList = Collections.synchronizedList(new ArrayList<>()); public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(30000); while(true) { // 此行代码会阻塞,将一直等待别人的连接 Socket s = ss.accept(); socketList.add(s); // 每当客户端连接后启动一条ServerThread线程为该客户端服务 new Thread(new ServerThread(s)).start(); } } } // 负责处理每个线程通信的线程类 public class ServerThread implements Runnable { // 定义当前线程所处理的Socket Socket s = null; // 该线程所处理的Socket所对应的输入流 BufferedReader br = null; public ServerThread(Socket s) throws IOException { this.s = s; // 初始化该Socket对应的输入流 br = new BufferedReader(new InputStreamReader(s.getInputStream())); } public void run() { try { String content = null; // 采用循环不断从Socket中读取客户端发送过来的数据 while ((content = readFromClient()) != null) { // 遍历socketList中的每个Socket, // 将读到的内容向每个Socket发送一次 for (Socket s : MyServer.socketList) { PrintStream ps = new PrintStream(s.getOutputStream()); ps.println(content); } } } catch (IOException e) { e.printStackTrace(); } } // 定义读取客户端数据的方法 private String readFromClient() { try { return br.readLine(); } // 如果捕捉到异常,表明该Socket对应的客户端已经关闭 catch (IOException e) { // 删除该Socket。 MyServer.socketList.remove(s); // ① } return null; } } public class MyClient { public static void main(String[] args)throws Exception { Socket s = new Socket("127.0.0.1" , 30000); // 客户端启动ClientThread线程不断读取来自服务器的数据 new Thread(new ClientThread(s)).start(); // ① // 获取该Socket对应的输出流 PrintStream ps = new PrintStream(s.getOutputStream()); String line = null; // 不断读取键盘输入 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); while ((line = br.readLine()) != null) { // 将用户的键盘输入内容写入Socket对应的输出流 ps.println(line); } } } public class ClientThread implements Runnable { // 该线程负责处理的Socket private Socket s; // 该线程所处理的Socket所对应的输入流 BufferedReader br = null; public ClientThread(Socket s) throws IOException { this.s = s; br = new BufferedReader(new InputStreamReader(s.getInputStream())); } public void run() { try { String content = null; // 不断读取Socket输入流中的内容,并将这些内容打印输出 while ((content = br.readLine()) != null) { System.out.println(content); } } catch (Exception e) { e.printStackTrace(); } } }