多人聊天室原理图
文章插图
文章插图
源码工具类:
该类用于关闭各种流 。
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();}}
先将服务器启动然后启动客户端:测试结果如下
文章插图
文章插图
有喜欢的小伙伴可以自己拿去玩 。代码复制直接有效 。
推荐阅读
- 是梨子有营养还是火龙果有营养?
- 《庆余年》里地主家傻儿子范思辙如此圈粉,如何评价郭麒麟饰演的该角色?
- 冬天吃什么水果比较好呢?
- 我的世界如何用指令附魔 我的世界手机版附魔指令分享
- 郭麒麟是曲艺传承人吗?你怎么看?
- 孩子吃什么水果最好?
- 中国十大药店连锁品牌 全国十大连锁药店排名
- 怎样钓草鱼最容易上钓 如何钓草鱼上鱼快
- 有人说郭麒麟在相声的路上越走越偏了,你同意这个观点吗?