多人聊天室原理图
文章插图
文章插图
源码工具类:
该类用于关闭各种流 。
【实现了微信群聊 微信群聊代码】publicclassCloseUtil{publicstaticvoidCloseAll(Closeable...closeable){for(Closeablec:closeable){if(c!=null){try{c.close();}catch(IOExceptione){e.printStackTrace();}}}}}
服务器:
服务器端创建一个serverSocket对象通过accept()方法监听是否有tcp连接 。同时有一个储存socket对象的集合将连接进来的对象储存到List集合中 。服务器将消息进行转发 。
//服务器publicclassServer{//存储每一个连接进来的客户端publicstaticList<MyChannel>list=newArrayList<>();publicstaticvoidmain(String[]args)throwsException{//创建ServerSocket对象ServerSocketserverSocket=newServerSocket(9999);while(true){//连接进来的客户端Socketclient=serverSocket.accept();System.out.println(client.getInetAddress()+"进入聊天室");MyChannelmyChannel=newMyChannel(client);list.add(myChannel);newThread(myChannel).start();}}}
消息转发类:
具体的消息转发实现类 。将信息发给除发送消息以外的其他客户端 。
//用于信息转发publicclassMyChannelimplementsRunnable{privateDataInputStreamdis;privateDataOutputStreamdos;privatebooleanflag=true;publicMyChannel(Socketsocket){try{dis=newDataInputStream(socket.getInputStream());dos=newDataOutputStream(socket.getOutputStream());}catch(IOExceptione){flag=false;CloseUtil.CloseAll(dis,dos);}}//接收数据的方法privateStringreceive(){Stringstr="";try{str=dis.readUTF();}catch(IOExceptione){flag=false;CloseUtil.CloseAll(dis,dos);Server.list.remove(this);}returnstr;}//发送数据的方法privatevoidsend(Stringstr){try{if(str!=null&&str.length()!=0){dos.writeUTF(str);dos.flush();}}catch(Exceptionexception){flag=false;CloseUtil.CloseAll(dos,dis);Server.list.remove(this);}}//转发消息的方法privatevoidsendToOther(){Stringstr=this.receive();List<MyChannel>list=Server.list;for(MyChannelother:list){if(other==list){continue;//不发送信息给自己}//将消息发送给其他客户端other.send(str);}}@Overridepublicvoidrun(){while(flag){sendToOther();}}}
发送信息类:
用于从键盘上获取数据然后将数据发送出去
publicclassSendimplementsRunnable{//从键盘上获取数据privateBufferedReaderbr;privateDataOutputStreamdos;privatebooleanflag=true;publicSend(){br=newBufferedReader(newInputStreamReader(System.in));}publicSend(Socketsocket){this();try{dos=newDataOutputStream(socket.getOutputStream());}catch(Exceptione){flag=false;CloseUtil.CloseAll(dos,socket);e.printStackTrace();}}privateStringgetMessage(){Stringstr="";try{str=br.readLine();}catch(IOExceptione){flag=false;CloseUtil.CloseAll(br);}returnstr;}privatevoidsend(Stringstr){try{dos.writeUTF(str);dos.flush();}catch(IOExceptione){flag=false;CloseUtil.CloseAll(dos);e.printStackTrace();}}@Overridepublicvoidrun(){while(flag){this.send(getMessage());}}}
信息接收类:
publicclassReceiveimplementsRunnable{//接受数据流privateDataInputStreamdis;privatebooleanflag=true;publicReceive(Socketsocket){try{dis=newDataInputStream(socket.getInputStream());}catch(Exceptione){flag=false;CloseUtil.CloseAll(dis,socket);}}privateStringgetMessage(){Stringstr="";try{str=dis.readUTF();}catch(IOExceptione){flag=false;CloseUtil.CloseAll(dis);e.printStackTrace();}returnstr;}@Overridepublicvoidrun(){while(flag){System.out.println(this.getMessage());}}}
客户端:
publicclassclient{publicstaticvoidmain(String[]args)throwsException{Socketsocket=newSocket(InetAddress.getLocalHost(),9999);Sendsend=newSend(socket);Receivereceive=newReceive(socket);newThread(send).start();newThread(receive).start();}}
先将服务器启动然后启动客户端:测试结果如下
文章插图
文章插图
有喜欢的小伙伴可以自己拿去玩 。代码复制直接有效 。
- 煲鸡汤要不要焯水
- 喝鸡汤有营养还是吃肉有营养
- 为什么快手红包抢不到 快手为什么抢不到红包了
- 手机丢了可以通过手机号定位吗 手机丢了可以通过手机号定位吗?
- 安装师傅怎么实现入驻天猫商城 淘宝安装师傅接单app不用交押金的
- 最成功的离婚拖延法 老公铁了心离婚妻子聪明做法
- 练八段锦皮肤会变好吗
- 猕猴桃坏了能不能吃
- 新鲜菇冰箱冷藏可以放多久
- 烟酰胺爽肤水可以湿敷吗