接《java Socket实现简单在线聊天(一)》,在单客户端连接的基础上,这里第二步需要实现多客户端的连接,也就需要使用到线程。每当有一个新的客户端连接上来,服务端便需要新启动一个线程进行处理,从而解决之前的循环读取中造成阻塞的问题。
写线程通常有两种方法,集成Thread或者实现runnable接口,原则上是能实现runnable的情况下就不继承,因为实现接口的方式更加灵活。
客户端代码相较之前没有变化,变得是服务端,因此这里便只贴出服务端代码:
package chat.chat; import java.io.DataInputStream; import java.io.EOFException; import java.io.IOException; import java.net.BindException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; /** * java使用socket和awt组件以及多线程简单实现在线聊天功能服务端 : 实现多个客户端连接后不断向服务端发送消息, * 相对于第一个版本,重点在于使用了多线程。服务端还未实现转发功能,客户端图形窗口中只能看到自己输入的信息, 不能看到其他客户端发送的消息 * * @author tuzongxun123 * */ public class ChatServer { public static void main(String[] args) { new ChatServer().start(); } // 是否成功启动服务端 private boolean isStart = false; // 服务端socket private ServerSocket ss = null; // 客户端socket private Socket socket = null; public void start() { try { // 启动服务器 ss = new ServerSocket(8888); } catch (BindException e) { System.out.println("端口已在使用中"); // 关闭程序 System.exit(0); } catch (Exception e) { e.printStackTrace(); } try { isStart = true; while (isStart) { // 启动监听 socket = ss.accept(); System.out.println("one client connect"); // 启动客户端线程 Client client = new Client(socket); new Thread(client).start(); } } catch (Exception e) { e.printStackTrace(); } finally { // 关闭服务 try { ss.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 客户端线程 * * @author tuzongxun123 * */ class Client implements Runnable { // 客户端socket private Socket socket = null; // 客户端输入流 private DataInputStream dataInputStream = null; private boolean isConnect = false; public Client(Socket socket) { this.socket = socket; try { isConnect = true; // 获取客户端输入流 dataInputStream = new DataInputStream(socket.getInputStream()); } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { isConnect = true; try { while (isConnect) { // 读取客户端传递的数据 String message = dataInputStream.readUTF(); System.out.println("客户端说:" + message); } } catch (EOFException e) { System.out.println("client closed!"); } catch (SocketException e) { System.out.println("Client is Closed!!!!"); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭相关资源 try { dataInputStream.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }