目标

完成一个群聊系统:

  1. 服务器可接收多个客户端的连接并接收信息
  2. 服务器向除了发送消息的客户端的其他客户端发送消息
  3. 客户端可以发送消息和接收消息

完成

服务器

package com.company.GroupChat;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;//群聊服务器
public class GroupChatServer {private final int Port = 9999;//使用到的属性private Selector selector;private ServerSocketChannel serverSocketChannel;private SocketChannel socketChannel;//构造器完成服务器连接操作public GroupChatServer() throws Exception {//打开selector和serverSocketChannelselector = Selector.open();serverSocketChannel = ServerSocketChannel.open();//设置非阻塞serverSocketChannel.configureBlocking(false);//监听端口serverSocketChannel.socket().bind(new InetSocketAddress(Port));//注册serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);}//读取消息的方法public static void main(String[] args) throws Exception {GroupChatServer server = new GroupChatServer();server.Listen();}//设置一个监听方法,监听事件public void Listen() throws Exception {while (true) {int cout=selector.select();//selector监控if (cout > 0) {//获得集合迭代器Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();while (keyIterator.hasNext()) {//得到该SelectionKeySelectionKey key = keyIterator.next();//判断事件if (key.isAcceptable()) {SocketChannel socketChannel = serverSocketChannel.accept();//设置非阻塞socketChannel.configureBlocking(false);//注册,监听读事件socketChannel.register(selector, SelectionKey.OP_READ);System.out.println("客户端:" + socketChannel.getRemoteAddress() + "  已上线");}if (key.isReadable()) {send(key);}//移除已经处理的SelectionKeykeyIterator.remove();}}//连接出现异常,应该是客户端下线}}//发送消息public void send(SelectionKey key) {//得到ChannelSocketChannel channel = null;//读取try {channel = (SocketChannel) key.channel();//创建bufferByteBuffer buffer = ByteBuffer.allocate(1024);int count = channel.read(buffer);//读取到了信息if (count > 0) {String msg = new String(buffer.array());System.out.println("客户端发送的消息:" + msg);//转发消息Forward(msg, channel);}} catch (IOException e) {try {System.out.println(channel.getRemoteAddress() + "已下线。。。");//取消注册key.cancel();//关闭通道channel.close();} catch (IOException e1) {e1.printStackTrace();}}}//转发消息的方法//需要知道消息和自身通道(转发除自身外的通道)public void Forward(String msg, SocketChannel self) throws IOException {System.out.println("消息转发中。。。");//得到所有注册在选择器上的通道for (SelectionKey key : selector.keys()) {//得到通道Channel channel = key.channel();//排除自己和非SocketChannelif (channel instanceof SocketChannel && channel != self) {SocketChannel sc = (SocketChannel) channel;//创建bufferByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());//写入sc.write(buffer);}}}
}

客户端

package com.company.GroupChat;import javafx.scene.transform.Scale;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;public class GroupChatClient {//常用的属性private  final String IP="127.0.0.1";private  final int Port=9999;private  Selector selector;private  SocketChannel socketChannel;private  String clientname;//构造方法public GroupChatClient() throws Exception{//打开selector = Selector.open();//连接socketChannel = SocketChannel.open(new InetSocketAddress(IP,Port));//设置非阻塞socketChannel.configureBlocking(false);//注册,监听read方法socketChannel.register(selector, SelectionKey.OP_READ);//得到客户端名字clientname=socketChannel.getLocalAddress().toString().substring(1);System.out.println(clientname+" 准备就绪。。。");}//接收信息public  void Receive() throws IOException {int sel=selector.select();//接收到事件if (sel > 0){//迭代得到的SelectionKey集合Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();while (iterator.hasNext()){//获得SelectionKeySelectionKey key = iterator.next();if (key.isReadable()){//得到通道SocketChannel channel = (SocketChannel)key.channel();//buffer获得信息ByteBuffer buffer = ByteBuffer.allocate(1024);//从通道中读出channel.read(buffer);System.out.println(new String(buffer.array()));}iterator.remove();}}elseSystem.out.println("没有可用通道");}public  void Send(String str) throws IOException {str=clientname+" : "+str;ByteBuffer buffer = ByteBuffer.wrap(str.getBytes());//写入socketChannel.write(buffer);}public static void main(String[] args) throws Exception {GroupChatClient chatClient=new GroupChatClient();new Thread(){public void run() {while (true){try {chatClient.Receive();Thread.currentThread().sleep(3000);} catch (IOException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}}}}.start();//发送数据Scanner scanner=new Scanner(System.in);//一行一行的输入while (scanner.hasNext()){String msg=scanner.nextLine();chatClient.Send(msg);}}}

结果

完成的代码步骤都在注释里

实验结果:
客户端连接时打印上线消息

客户端发送消息:

服务器转发:

其他客户端接收消息:

Java网络编程(9)NIO - 群聊系统相关推荐

  1. (六)Netty网络编程应用实例-群聊系统

    实例要求: 编写一个NIO群聊系统,实现服务器端和客户端之间的数据简单通讯(非阻塞) 实现多人群聊 服务器端:可以监测用户上线,离线,并实现消息转发功能 客户端:通过channel可以无阻塞发送消息给 ...

  2. NIO网络编程应用实例——群聊系统

    GroupChatServer.java package com.atguigu.nio.groupchat;import java.io.IOException; import java.net.I ...

  3. Java NIO群聊系统

    实例要求: 1.编写一个 NIO 群聊系统,实现服务器端和客户端之间的数据简单通讯(非阻塞) 2.实现多人群聊 3.服务器端:可以监测用户上线,离线,并实现消息转发功能 4.客户端:通过 Channe ...

  4. Java网络编程与NIO学习总结

    #Java网络编程与NIO学习总结 这篇总结主要是基于我之前Java网络编程与NIO系列文章而形成的的.主要是把重要的知识点用自己的话说了一遍,可能会有一些错误,还望见谅和指点.谢谢 #更多详细内容可 ...

  5. Java网络编程和NIO详解开篇:Java网络编程基础

    老曹眼中的网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为我们拥有网络.网络是一个神奇的东西,它改变了你和我的 ...

  6. 手写一个NIO群聊系统

    一.浅谈NIO 1. 什么是NIO? ​​Java NIO​​:同步非阻塞,服务器实现模式为一个线程处理多个请求(连接),即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有 ​​I/ ...

  7. java 网络编程和NIO

    1.软件结构 C/S结构 :全称为Client/Server结构,是指客户端和服务器结构.常见程序有QQ.迅雷等软件. 特点: 客户端和服务器是分开的,需要下载客户端,对网络要求相对低, 服务器压力小 ...

  8. Java网络编程与NIO详解14:Tomcat 常见面试题汇总

    1.Tomcat的缺省端口是多少,怎么修改? 1)找到Tomcat目录下的conf文件夹 2)进入conf文件夹里面找到server.xml文件 3)打开server.xml文件 4)在server. ...

  9. Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制

    JAVA 中原生的 socket 通信机制 转载自:https://github.com/jasonGeng88/blog 当前环境 jdk == 1.8 知识点 socket 的连接处理 IO 输入 ...

  10. java网络编程3 -- NIO一些简单说明

    2019独角兽企业重金招聘Python工程师标准>>> 什么是NIO NIO是相对有BIO而言的,就是非阻塞性IO . 什么叫非阻塞性 ?我举一个简单的例子: 比如,你客户端发送了一 ...

最新文章

  1. Python基础之函数2 (参数的返回值)
  2. Nginx动态、静态分离,Nginx配置中做适配
  3. 关于类DOTA游戏多样化技能系统的设计思考
  4. php 代码如何使用,PHP如何使用strval()函数?用法和代码示例
  5. JUnit4参数化和理论示例
  6. php mvc 高性能框架,swoolefy-基于swoole扩展实现的高性能的微服务和mvc框架
  7. 互联网晚报 | 9月5日 星期日 | 美菜回应大规模裁员;网易云音乐Q2毛利率首次转正;美团展示数字人民币新应用...
  8. 罗永浩“真还传”再出番外篇,被执行1800万,交个朋友回应来了…
  9. redis永久化存储
  10. 使用IPV6 ACL对telnet登陆进行限定
  11. 独立的定义有多重等价表述方式
  12. 矩阵论第一章总结(思维导图)
  13. 正则表达式最后的/i是不区分大小写的意思
  14. 药店计算机无法运行整改报告,药店整改报告模板网络版(电子版)
  15. Axure 9 实战案例,动态面板的应用 3,京东的拖动拼图登录验证
  16. 2017.10.14晚,用迅雷下载大部分BT资源出现失败,tracker服务器被封了?FK
  17. 裁剪用C语言,多边形裁剪
  18. 解决QT-mingw32编译“ too many sections(...)”问题
  19. 最新友价T5仿虚拟交易商城网站源码+PHP内核
  20. 几种Java常用序列化框架的选型与对比

热门文章

  1. 学计算机要学工图吗,工程图学及计算机绘图: 非机类
  2. 智能驾驶浪潮催生车载通信新机遇 移远通信抢占5G+C-V2X+GNSS风口
  3. 第三方SDK:SMSSDK
  4. 西柚SWPU新生赛(场外同步赛)miscAK 别的在混(
  5. 【软件设计师考试】《软件设计师教程》(一)
  6. 从源程序到可执行文件的四个过程
  7. 高通7227平台外接UBLOX的GPS模块数据接收不稳定问题
  8. 计算机网络原理的思维导图汇总
  9. 解决“gettools.exe 已停止工作”问题
  10. 多元统计分析假设检验