GroupChatServer.java


package com.atguigu.nio.groupchat;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;public class GroupChatServer {//定义属性private Selector selector;private ServerSocketChannel listenChannel;private static final int PORT = 6667;//构造器//初始化工作public GroupChatServer() {try {//得到选择器selector = Selector.open();//ServerSocketChannellistenChannel =  ServerSocketChannel.open();//绑定端口listenChannel.socket().bind(new InetSocketAddress(PORT));//设置非阻塞模式listenChannel.configureBlocking(false);//将该listenChannel 注册到selectorlistenChannel.register(selector, SelectionKey.OP_ACCEPT);}catch (IOException e) {e.printStackTrace();}}//监听public void listen() {System.out.println("监听线程: " + Thread.currentThread().getName());try {//循环处理while (true) {int count = selector.select();if(count > 0) {//有事件处理//遍历得到selectionKey 集合Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();while (iterator.hasNext()) {//取出selectionkeySelectionKey key = iterator.next();//监听到acceptif(key.isAcceptable()) {SocketChannel sc = listenChannel.accept();sc.configureBlocking(false);//将该 sc 注册到seletorsc.register(selector, SelectionKey.OP_READ);//提示System.out.println(sc.getRemoteAddress() + " 上线 ");}if(key.isReadable()) { //通道发送read事件,即通道是可读的状态//处理读 (专门写方法..)readData(key);}//当前的key 删除,防止重复处理iterator.remove();}} else {System.out.println("等待....");}}}catch (Exception e) {e.printStackTrace();}finally {//发生异常处理....}}//读取客户端消息private void readData(SelectionKey key) {//取到关联的channelSocketChannel channel = null;try {//得到channelchannel = (SocketChannel) key.channel();//创建bufferByteBuffer buffer = ByteBuffer.allocate(1024);int count = channel.read(buffer);//根据count的值做处理if(count > 0) {//把缓存区的数据转成字符串String msg = new String(buffer.array());//输出该消息System.out.println("form 客户端: " + msg);//向其它的客户端转发消息(去掉自己), 专门写一个方法来处理sendInfoToOtherClients(msg, channel);}}catch (IOException e) {try {System.out.println(channel.getRemoteAddress() + " 离线了..");//取消注册key.cancel();//关闭通道channel.close();}catch (IOException e2) {e2.printStackTrace();;}}}//转发消息给其它客户(通道)private void sendInfoToOtherClients(String msg, SocketChannel self ) throws  IOException{System.out.println("服务器转发消息中...");System.out.println("服务器转发数据给客户端线程: " + Thread.currentThread().getName());//遍历 所有注册到selector 上的 SocketChannel,并排除 selffor(SelectionKey key: selector.keys()) {//通过 key  取出对应的 SocketChannelChannel targetChannel = key.channel();//排除自己if(targetChannel instanceof  SocketChannel && targetChannel != self) {//转型SocketChannel dest = (SocketChannel)targetChannel;//将msg 存储到bufferByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());//将buffer 的数据写入 通道dest.write(buffer);}}}public static void main(String[] args) {//创建服务器对象GroupChatServer groupChatServer = new GroupChatServer();groupChatServer.listen();}
}

GroupChatClient.java

package com.atguigu.nio.groupchat;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;public class GroupChatClient {//定义相关的属性private final String HOST = "127.0.0.1"; // 服务器的ipprivate final int PORT = 6667; //服务器端口private Selector selector;private SocketChannel socketChannel;private String username;//构造器, 完成初始化工作public GroupChatClient() throws IOException {selector = Selector.open();//连接服务器socketChannel = socketChannel.open(new InetSocketAddress("127.0.0.1", PORT));//设置非阻塞socketChannel.configureBlocking(false);//将channel 注册到selectorsocketChannel.register(selector, SelectionKey.OP_READ);//得到usernameusername = socketChannel.getLocalAddress().toString().substring(1);System.out.println(username + " is ok...");}//向服务器发送消息public void sendInfo(String info) {info = username + " 说:" + info;try {socketChannel.write(ByteBuffer.wrap(info.getBytes()));}catch (IOException e) {e.printStackTrace();}}//读取从服务器端回复的消息public void readInfo() {try {int readChannels = selector.select();if(readChannels > 0) {//有可以用的通道Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();while (iterator.hasNext()) {SelectionKey key = iterator.next();if(key.isReadable()) {//得到相关的通道SocketChannel sc = (SocketChannel) key.channel();//得到一个BufferByteBuffer buffer = ByteBuffer.allocate(1024);//读取sc.read(buffer);//把读到的缓冲区的数据转成字符串String msg = new String(buffer.array());System.out.println(msg.trim());}}iterator.remove(); //删除当前的selectionKey, 防止重复操作} else {//System.out.println("没有可以用的通道...");}}catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) throws Exception {//启动我们客户端GroupChatClient chatClient = new GroupChatClient();//启动一个线程, 每个3秒,读取从服务器发送数据new Thread() {public void run() {while (true) {chatClient.readInfo();try {Thread.currentThread().sleep(3000);}catch (InterruptedException e) {e.printStackTrace();}}}}.start();//发送数据给服务器端Scanner scanner = new Scanner(System.in);while (scanner.hasNextLine()) {String s = scanner.nextLine();chatClient.sendInfo(s);}}}

NIO网络编程应用实例——群聊系统相关推荐

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

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

  2. Netty学习笔记:二、NIO网络应用实例-群聊系统

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

  3. Netty专题-(3)NIO网络编程

    之前在上一章Netty专题-(2)NIO三大核心中介绍了NIO的三大核心类Selector . Channel 和 Buffer,这一章我们将利用这些核心进行编程实现相关的一些功能.在正式进入编程之前 ...

  4. Java NIO网络编程之群聊系统

    概述 对ServerSocketChannel.SocketChannel.SelectionKey有一定的理解和了解对应API. NIO非阻塞网络编程相关关系梳理: 以下概念: ServerSock ...

  5. Java NIO群聊系统

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

  6. 手写一个NIO群聊系统

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

  7. 4.基于NIO的群聊系统

    [README] 1.本文总结自B站<netty-尚硅谷>,很不错: 2.文末有错误及解决方法: [1]群聊需求 1)编写一个 NIO 群聊系统,实现服务器端和客户端之间的数据简单通讯(非 ...

  8. Java NIO 应用案例:实现一个简单的群聊系统

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

  9. Java基础之《netty(18)—群聊系统》

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

最新文章

  1. linq.designer.cs学习笔记
  2. [深度学习] Keras 如何使用fit和fit_generator
  3. React的生命周期(旧)
  4. qc成果报告范例_QC推进这样做才是货真价值!| 看机电股份的QC报告
  5. 2019年,北大毕业生都去哪儿了?
  6. EhCache缓存在web下的使用实例
  7. 如何扩大网站访问,五种方法让问题不再难
  8. RabbitMQ的消息确认、消息持久化
  9. multisim 10 基本分析法的应用1
  10. 明白熊猫与冰墩墩的区别,就知道青云KubeSphere与QKCP该如何选择
  11. 全网音乐Music Download v2.1.2
  12. U盘怎么写保护、去保护?
  13. linux更新后不能进入系统,Ubuntu内核升级后无法进入系统的解决办法
  14. 前百度副总裁王京傲出任云骥智行CTO ,All in自动驾驶
  15. 火狐html显示黑点
  16. 十大密码攻击及缓解措施
  17. ④911 计算机专业基础,2017年北京物资学院计算机应用技术911计算机学科专业基础综合之计算机组成原理考研仿真模拟题...
  18. 利用电影贴吧引流轻松变现,超适合新手
  19. java 发邮件授权码_javamail - androidmail 发送邮件 各种邮件授权方式
  20. 实验四+087+饶慧敏

热门文章

  1. python浅拷贝和深拷贝
  2. bzoj 4547: Hdu5171 小奇的集合
  3. redis的入门篇----启动和关闭
  4. MySQL 5.6.26 通过frm ibd 恢复数据过程
  5. hibernate小记
  6. C++Primer 第一章 快速入门 学习
  7. 单元测试之道一:NUnit基础
  8. Android KeyCode列表
  9. 递归三:变态蛙跳台阶
  10. vCenter6.0配置二:配置HA群集