Socket|Socket 实现(一对多)聊天室(多线程)代码+注释

1.使用server.accept()实现链接,开线程处理socket实例处理信息交互。
2.控制输出同时使用线程接收服务端返回的信息,
ps:
Server服务端代码如下:

import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.Collection; /** * 服务端 * 处理多个client连接任务 * @author natcheng * */ public class Server { private ServerSocket server; //所有的客户端信息流 private Collection【Socket|Socket 实现(一对多)聊天室(多线程)代码+注释】 allpw = new ArrayList(); /** * 构造:初始成员变量 */ public Server() { try { System.out.println("Server is starting..."); server = new ServerSocket(8088); System.out.println("Server is ready!"); } catch (IOException e) { e.printStackTrace(); } } /** * 服务端启动连接客户端并处理信息交互 */ public void start() { try { //accept()方法对接客户端形成socket实例 System.out.println("Ready for client..."); Socket socket = server.accept(); System.out.println("Connection succeeded!"); //开线程接client Runnable r1 = new ClientHandler(socket); Thread t1 = new Thread(r1); t1.start(); } catch (IOException e) { e.printStackTrace(); } } /** * 内部类,实现开线程接待Client中的Socket实例信息交互 * @author soft01 * */ private class ClientHandler implements Runnable{ private Socket socket; private String host; /** * 内部类构造,接accept()返回的socket * @param socket */ public ClientHandler(Socket socket) { this.socket = socket; InetAddress it = socket.getInetAddress(); this.host = it.getHostAddress(); } /** * 线程方法run */ PrintWriter pw; public void run() { Thread t = Thread.currentThread(); try { BufferedReader br = new BufferedReader( new InputStreamReader(socket.getInputStream(),"UTF-8")); pw = new PrintWriter( new BufferedWriter( new OutputStreamWriter( socket.getOutputStream(),"UTF-8")),true); synchronized(allpw) { allpw.add(pw); System.out.println("同时在线人数:"+allpw.size()); } String clientMsg = null; while(t.isAlive()) { if((clientMsg=br.readLine())!= null) { System.out.println(clientMsg); } //同时返回给各个客户端这条信息: synchronized(allpw) { for(PrintWriter everyPw:allpw) { everyPw.println(host+"说:"+clientMsg); } } } } catch (IOException e) { e.printStackTrace(); } finally { //下线踢除pw if(t.isInterrupted()) { synchronized(allpw) { allpw.remove(pw); } System.out.println(host+",offline!"); //socket关闭 try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } } public static void main(String[] args) { Server server = new Server(); server.start(); } }

Client 客户端代码如下:
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.util.Scanner; /** * 客户端 * @author soft01 * */ public class Client { private Socket socket; /** * 构造:初始化socket,连接服务端 */ public Client() { try { System.out.println("Client is starting..."); this.socket=new Socket("localhost",8088); System.out.println("Client start successfully!"); } catch (IOException e) { e.printStackTrace(); } } /** * 启动信息交互 */ public void start() { //发送信息(开线程) Runnable r = new OutputMsg(); Thread t = new Thread(r); t.start(); //接收信息 try { BufferedReader br = new BufferedReader( new InputStreamReader(socket.getInputStream(),"UTF-8")); String serverMsg = null; while((serverMsg=br.readLine())!= null) { System.out.println(serverMsg); } } catch (IOException e) { e.printStackTrace(); } } private class OutputMsg implements Runnable{ public void run() { try { PrintWriter pw = new PrintWriter( new BufferedWriter ( new OutputStreamWriter(socket.getOutputStream(),"UTF-8")),true); System.out.println("input msg:"); Scanner scan = new Scanner(System.in); String inputMsg = scan.nextLine(); pw.println(inputMsg); } catch (IOException e) { e.printStackTrace(); } } } /** * 主方法 * @param args */ public static void main(String[] args) { Client client = new Client(); client.start(); } }

    推荐阅读