服务端: 

package cn.zhangxueliang.herostory.chatroom;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;/*** @ProjectName herostory3* @ClassName ChatRoomServer* @Desicription TODO* @Author Zhang Xueliang* @Date 2019/12/11 13:58* @Version 1.0**  * 网络多客户端聊天室*  * 功能1: 客户端通过Java NIO连接到服务端,支持多客户端的连接*  * 功能2:客户端初次连接时,服务端提示输入昵称,如果昵称已经有人使用,提示重新输入,如果昵称唯一,则登录成功,之后发送消息都需要按照规定格式带着昵称发送消息*  * 功能3:客户端登录后,发送已经设置好的欢迎信息和在线人数给客户端,并且通知其他客户端该客户端上线*  * 功能4:服务器收到已登录客户端输入内容,转发至其他登录客户端。*  **  * TODO 客户端下线检测***/
public class ChatRoomServer {private Selector selector=null;static final int port=9999;private Charset charset=Charset.forName("UTF-8");private static HashSet<String> users = new HashSet<>();private static String USER_EXIST="system message : user exist, please change a name用户名已存在,请更换一个名称";private static String USER_CONTENT_SPLIT="#@#";private static boolean flag=false;public void init() throws Exception{selector=Selector.open();ServerSocketChannel server = ServerSocketChannel.open();server.bind(new InetSocketAddress(port));server.configureBlocking(false);server.register(selector, SelectionKey.OP_ACCEPT);System.out.println("Server is listening now...服务端正在监听中");while (true){int readyChannels = selector.select();if (readyChannels==0){continue;}Set<SelectionKey> selectionKeys = selector.selectedKeys(); //可以通过这个方法,知道可用通道的集合Iterator<SelectionKey> keyIterator = selectionKeys.iterator();while (keyIterator.hasNext()){SelectionKey sk = keyIterator.next();keyIterator.remove();dealWithSelectionKey(server,sk);}}}private void dealWithSelectionKey(ServerSocketChannel server, SelectionKey sk) throws IOException {if (sk.isAcceptable()){SocketChannel sc = server.accept();sc.configureBlocking(false);sc.register(selector,SelectionKey.OP_READ);sk.interestOps(SelectionKey.OP_ACCEPT);System.out.println("Server is listening fron client: "+sc.getRemoteAddress());sc.write(charset.encode("please input your name."));}if (sk.isReadable()){SocketChannel sc = (SocketChannel) sk.channel();ByteBuffer buff = ByteBuffer.allocate(1024);StringBuilder content = new StringBuilder();try{while (sc.read(buff)>0){buff.flip();content.append(charset.decode(buff));}System.out.println("Server is listening from client: "+sc.getRemoteAddress()+" data rev is: "+content);sk.interestOps(SelectionKey.OP_READ);}catch (IOException io){sk.cancel();if (sk.channel()!=null){sk.channel().close();}}if (content.length()>0){String[] arrayContent = content.toString().split(USER_CONTENT_SPLIT);if (arrayContent!=null && arrayContent.length==1){String name = arrayContent[0];if (users.contains(name)){sc.write(charset.encode(USER_EXIST));}else {users.add(name);int num = OnlineNum(selector);String message = "welcome "+name+" to char room! Online numbers is :"+num;BroadCast(selector,null,message);}}else if (arrayContent!=null && arrayContent.length>1){String name = arrayContent[0];String message = content.substring(name.length()+USER_CONTENT_SPLIT.length());message=name+" say "+message;if (users.contains(name)){BroadCast(selector,sc,message);}}}}}private void BroadCast(Selector selector, SocketChannel except, String content) throws IOException {for (SelectionKey key:selector.keys()){Channel targetchannel = key.channel();if (targetchannel instanceof SocketChannel && targetchannel!=except){SocketChannel dest = (SocketChannel) targetchannel;dest.write(charset.encode(content));}}}private int OnlineNum(Selector selector) {int res=0;for (SelectionKey key:selector.keys()){SelectableChannel targetChannel = key.channel();if (targetChannel instanceof SocketChannel){res++;}}return res;}public static void main(String[] args) throws Exception {new ChatRoomServer().init();}}

客户端:

package cn.zhangxueliang.herostory.chatroom;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
import java.nio.ByteBuffer;
/*** @ProjectName herostory3* @ClassName ChatRoomClient* @Desicription TODO* @Author Zhang Xueliang* @Date 2019/12/11 14:33* @Version 1.0**/
public class ChatRoomClient {private Selector selector = null;static final int port = 9999;private Charset charset = Charset.forName("UTF-8");private SocketChannel sc = null;private String name = "";private static String USER_EXIST = "system message: user exist, please change a name";private static String USER_CONTENT_SPILIT = "#@#";public void init() throws IOException{selector = Selector.open();//连接远程主机的IP和端口sc = SocketChannel.open(new InetSocketAddress("127.0.0.1",port));sc.configureBlocking(false);sc.register(selector, SelectionKey.OP_READ);//开辟一个新线程来读取从服务器端的数据new Thread(new ClientThread()).start();//在主线程中 从键盘读取数据输入到服务器端Scanner scan = new Scanner(System.in);while(scan.hasNextLine()){String line = scan.nextLine();if("".equals(line)) continue; //不允许发空消息if("".equals(name)) {name = line;line = name+USER_CONTENT_SPILIT;} else {line = name+USER_CONTENT_SPILIT+line;}sc.write(charset.encode(line));//sc既能写也能读,这边是写}}private class ClientThread implements Runnable{public void run(){try{while(true) {int readyChannels = selector.select();if(readyChannels == 0) continue;Set selectedKeys = selector.selectedKeys();  //可以通过这个方法,知道可用通道的集合Iterator keyIterator = selectedKeys.iterator();while(keyIterator.hasNext()) {SelectionKey sk = (SelectionKey) keyIterator.next();keyIterator.remove();dealWithSelectionKey(sk);}}}catch (IOException io){}}private void dealWithSelectionKey(SelectionKey sk) throws IOException {if(sk.isReadable()){//使用 NIO 读取 Channel中的数据,这个和全局变量sc是一样的,因为只注册了一个SocketChannel//sc既能写也能读,这边是读SocketChannel sc = (SocketChannel)sk.channel();ByteBuffer buff = ByteBuffer.allocate(1024);String content = "";while(sc.read(buff) > 0){buff.flip();content += charset.decode(buff);}//若系统发送通知名字已经存在,则需要换个昵称if(USER_EXIST.equals(content)) {name = "";}System.out.println(content);sk.interestOps(SelectionKey.OP_READ);}}}public static void main(String[] args) throws IOException{new ChatRoomClient().init();}
}

Java NIO示例:多人网络聊天室完整代码相关推荐

  1. Netty网络聊天室完整代码实现

    Netty服务端: package cn.zhangxueliang.netty.chat;import io.netty.bootstrap.ServerBootstrap; import io.n ...

  2. java源码聊天软件_【原创】基于Java NIO的多人在线聊天工具源码实现(登录,单聊,群聊)...

    近来在学习Java NIO网络开发知识,写了一个基于Java NIO的多人在线聊天工具MyChat练练手.源码公开在Coding上: 编写一个基于Java NIO的多人在线聊天工具,需要以下几方面的知 ...

  3. 视频教程-Java基础中国象棋和网络聊天室Swing开发-Java

    Java基础中国象棋和网络聊天室Swing开发 IT行业资深从业者,7年资深Java高级开发,Java架构师.曾就职银行.电信等行业多家上市公司.担任项目负责人,软件架构师.有丰富的高并发.分布式系统 ...

  4. Linux C多人网络聊天室

    经过好几天的日夜奋斗,总算把这个聊天室给做出来了,虽然说不上多好,但也是这几天从早到晚劳动的成功,所以就写这篇博文来记录一下啦.别的不敢说,确保能用就是了,完整代码在最后哦~ 当然啦,如果有幸被转发, ...

  5. 视频教程-多人网络聊天室-Unity3D

    多人网络聊天室 广州市码锋网络有限责任公司创始人,从事游戏开发九年,熟练前后端的各种技术,我很乐意将企业中商用的技术分享给你,帮助你解决工作的各种问题. 官剑铭 ¥39.00 立即订阅 扫码下载「CS ...

  6. QQ版网络聊天室完整项目+MFC\C++\C(更改服务器IP可实现异机沟通)

    QQ版网络聊天室完整项目+MFC\C++\C 资源地址1 资源地址2 项目简介 服务器端部分代码 客户端响应部分代码 数据库连接 理论~ 实例展示 资源地址1 https://github.com/M ...

  7. JAVA 基于TCP的多人网络聊天室 实现过程

    主要实现功能 多人在线聊天 发送私密消息 新用户加入提示 用户离开提示 功能演示 服务器: package dome;import java.io.DataInputStream; import ja ...

  8. 【python】实现多人网络聊天室

    利用socket套接字实现多台计算机之间的连接 server: import socket #socket 是一种套接字,用来描述IP和port import os import threading ...

  9. Java NIO示例:多人网络聊天室

    一个多客户端聊天室,支持多客户端聊天,有如下功能: 功能1: 客户端通过Java NIO连接到服务端,支持多客户端的连接 功能2:客户端初次连接时,服务端提示输入昵称,如果昵称已经有人使用,提示重新输 ...

最新文章

  1. Silverlight实用窍门系列:40.Silverlight中捕捉视频,截图保存到本地
  2. Hibernate5-唯一查询和聚合查询
  3. c语言prog.c: in function 'main':,C语言 tr1 :: function和tr1 :: bind
  4. mpvue生命周期初探
  5. 【NLP】NLP模型BERT和经典数据集!
  6. android里面画布快照,自定义 View - Canvas - 画布操作和快照
  7. Qt工作笔记-如何正确使用QXmlStreamReader(学会利用错误提示)
  8. VS Code创建C项目
  9. 在MongoDB的MapReduce上踩过的坑
  10. vue2.x 给一个对象里添加一个没有的属性
  11. 向网页中插入透明Flash的方法和技巧
  12. 认识CodeSmith
  13. 联想拯救者Legion Y7000P 2020款安装ubuntu16.04 解决WIFI 显卡 cuda10.2)
  14. 【Office】wps表格如何让后面的单元格随着下拉选项自动填充
  15. 本地音乐如何导入apple_如何将自己的音乐添加到Apple Music
  16. 我慌了!我妈从床底掏出了我珍藏多年的小本本-----JAVA_Lambda表达式(笔记)
  17. win7记事本如何转换html,记事本格式_win7记事本怎么改格式
  18. 【目标规划】暑假计划
  19. 扫描二维码下载app,判断是Android还是ios,并跳转到不同的下载地
  20. 图片识别 就用uu云验证码识别平台

热门文章

  1. 【机器学习基础】机器学习小抄.pdf(像背托福单词一样理解机器学习)
  2. 【职场】什么是 “职场PUA” ?
  3. 从 Google 的一道面试题谈谈数学基础的重要性
  4. 推荐系统炼丹笔记:令人着迷的时间动态CF算法
  5. 互联网1分钟 | 0321 小米上线“朕惊视频”;依图医疗与华为联合发布智能医疗云...
  6. MCtalk对话兰迪少儿英语:1v1不具普适性,小班课才是下个风口
  7. React事件系统研究总结
  8. Python之面向对象继承和派生
  9. 基于环信的仿QQ即时通讯的简单实现
  10. 【新年快乐】缤纷多彩的Vue点赞组件