简单聊天室 java,java实现一个简易的聊天室
本文实例为大家分享了爪哇实现简单聊天室功能的具体代码,供大家参考,具体内容如下
一、客户端的创建
1.我们可以用窝来创建客户端
/** *@类名客户端*@描述待办事项客户端1 *@版本1.0 *@创建人徐康*@创建时间2020/9/24 16:18 * */公共类客户端{ public static void main(String[]args)抛出未知主机异常,io异常{系统。出去。println(-客户端1-);缓冲读取器br=新缓冲读取器(新输入流读取器(系统。in));System.out.println(请输入用户名:);string name=br。readline();//1、建立连接: 使用窝创建客户端服务的地址和端口套接字客户端=新套接字( localhost ,8888);//2、客户端发送消息新线程(新发送(客户端,名称))。start();新线程(新接收(客户端))。start();}}2.这时我们需要接受其他客户端发送的数据,我们需要创建一个客户端的接收方法和发送方法,我可以用阻塞式的方式进行接收和发送,考虑到多线程的安全性,可以实现可追捕的
1.派遣发送端:
/** *@类名发送*@描述待办事项使用多线程封装:发送端*@版本1.0 *@创建人徐康*@创建时间2020/9/24 16:23 * */公共类发送实现Runnable { private BufferedReader控制台;私有数据输出流dos私有套接字客户端;私有布尔值正在运行;私有字符串名称;公共发送(套接字客户端,字符串名称){ this . client=client console=new buffered reader(new InputStreamReader(system。in));this . is running=true this . name=name请尝试{ dos=新数据输出流(客户端。获取输出流());//发送名称发送(姓名);} catch(io异常e){ system。出去。println(==1==);这个。发布();} } @ Override public void run(){ while(正在运行){ String msg=getStrFromConsole();如果(!味精。equals(){ send(msg);} } } //发送消息private void send(String msg){ try { dos。写utf(msg);dos。flush();} catch(io异常e){ system。出去。println(e);系统。出去。println(===3==);发布();} } /** * 从控制台获取消息* @ return */private String getStrFromConsole(){ try { return console。readline();} catch(io异常e){ e . printstacktrace();} return“”;
} //释放资源 private void release() { this.isRunning = false; CloseUtils.close(dos,client); }}2.接收端
/** *@类名 Receive *@描述 TODO 使用多线程封装:接收端 *@版本 1.0 *@创建人 XuKang *@创建时间 2020/9/24 16:22 **/public class Receive implements Runnable { private DataInputStream dis ; private Socket client; private boolean isRunning; public Receive(Socket client) { this.client = client; this.isRunning = true; try { dis =new DataInputStream(client.getInputStream()); } catch (IOException e) { System.out.println("====离开一位====="); release(); } } //接收消息 private String receive() { String msg =""; try { msg =dis.readUTF(); } catch (IOException e) { System.out.println("====接收消息异常===="); release(); } return msg; } @Override public void run() { while(isRunning) { String msg =receive(); if(!msg.equals("")) { System.out.println(msg); } } } //释放资源 private void release() { this.isRunning = false; CloseUtils.close(dis,client); }}
3.统一释放资源的方法可以提出,服务的也用得上
/** *@类名 CloseUtils *@描述 TODO 工具类,统一释放资源 *@版本 1.0 *@创建人 XuKang *@创建时间 2020/9/24 16:20 **/public class CloseUtils { /** * 释放资源 */ public static void close(Closeable... targets ) { for(Closeable target:targets) { try { if(null!=target) { target.close(); } }catch(Exception e) { } } }}
二、客户端的创建
服务端用ServerSocket创建,如果我们吧服务的和客户端看成事一个通信通道(Channel),那么每个客户端的接入都会创建一个通信通道,那么通信通道的创建也需要实现多线程,可以实现Runnable接口,我们存放通道可以用线程容器CopyOnWriteArrayList来存放通道。
/** *@类名 Chat *@描述 TODO Socket服务端(测试类) *@版本 1.0 *@创建人 XuKang *@创建时间 2020/9/24 16:17 **/public class Chat { private static CopyOnWriteArrayList<Channel> all =new CopyOnWriteArrayList<Channel>(); public static void main(String[] args) throws IOException { System.out.println("-----Server-----"); // 1、指定端口 使用ServerSocket创建服务器 ServerSocket server =new ServerSocket(8888); // 2、阻塞式等待连接 accept while(true) { Socket client =server.accept(); System.out.println("一个客户端建立了连接"); Channel c =new Channel(client); all.add(c); //管理所有的成员 new Thread(c).start(); } } //一个客户代表一个Channel static class Channel implements Runnable{ private DataInputStream dis; private DataOutputStream dos; private Socket client; private boolean isRunning; private String name; public Channel(Socket client) { this.client = client; try { dis = new DataInputStream(client.getInputStream()); dos =new DataOutputStream(client.getOutputStream()); isRunning =true; //获取名称 this.name =receive();//退出出聊天室 //欢迎你的到来 this.send("欢迎你的到来"); sendOthers(this.name+"来了徐康聊天室",true);//暂时固定为私聊 } catch (IOException e) { System.out.println("---1------"); release(); } } //接收消息 private String receive() { String msg =""; try { msg =dis.readUTF(); } catch (IOException e) { System.out.println("---2------"); release(); } return msg; } //发送消息 private void send(String msg) { try { dos.writeUTF(msg); dos.flush(); } catch (IOException e) { System.out.println("---3------"); release(); } } /** * @方法名 sendOthers * @描述 TODO 群聊:获取自己的消息,发给其他人,需要设置isSys为false * TODO 私聊: 约定数据格式: @xxx:msg * @参数 msg 发送内容 * @返回值 * @创建人 XuKang * @创建时间 2020/9/24 16:28 */ private void sendOthers(String msg,boolean isSys) { boolean isPrivate = msg.startsWith("@"); if(isPrivate) { //私聊 int idx =msg.indexOf(":"); //获取目标和数据 String targetName = msg.substring(1,idx); msg = msg.substring(idx+1); for(Channel other: all) { if(other.name.equals(targetName)) {//目标 other.send(this.name +"悄悄地对您说:"+msg); break; } } }else { for(Channel other: all) { if(other==this) { //自己 continue; } if(!isSys) { other.send(this.name +"对所有人说:"+msg);//群聊消息 }else { other.send(msg); //系统消息 } } } } //释放资源 private void release() { this.isRunning = false; CloseUtils.close(dis,dos,client); //退出 all.remove(this); sendOthers(this.name+"离开大家庭...",true); } @Override public void run() { while(isRunning) { String msg = receive() ; if(!msg.equals("")) { //send(msg); sendOthers(msg,false); } } } }}
三、效果如下
1.启动服务端
2.启动客户端
3.发送消息
&nb
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。