广告
返回顶部
首页 > 资讯 > 精选 >Java怎么实现NIO聊天室
  • 474
分享到

Java怎么实现NIO聊天室

2023-06-15 01:06:01 474人浏览 薄情痞子
摘要

这篇文章给大家分享的是有关Java怎么实现NIO聊天室的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。功能介绍功能:群聊+私发+上线提醒+下线提醒+查询在线用户文件Utils需要用maven导入下面两个包 

这篇文章给大家分享的是有关Java怎么实现NIO聊天室的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

功能介绍

功能:群聊+私发+上线提醒+下线提醒+查询在线用户

Java怎么实现NIO聊天室

Java怎么实现NIO聊天室

Java怎么实现NIO聊天室

Java怎么实现NIO聊天室

文件

Utils

需要用maven导入下面两个包

 <dependency>            <groupId>org.projectlombok</groupId>            <artifactId>lombok</artifactId>            <version>1.16.18</version>        </dependency>        <dependency>            <groupId>ch.qos.logback</groupId>            <artifactId>logback-classic</artifactId>            <version>1.2.3</version>        </dependency>
package moremorechat_nio;import lombok.extern.slf4j.Slf4j;import java.io.*;@Slf4jpublic class Utils {        public static Message decode(byte[] buf) throws IOException, ClassNotFoundException {        ByteArrayInputStream bais = new ByteArrayInputStream(buf);        ObjectInputStream ois = new ObjectInputStream(bais);        return (Message) ois.readObject();    }        public static byte[] encode(Message message) throws IOException {        ByteArrayOutputStream baos = new ByteArrayOutputStream();        ObjectOutputStream oos = new ObjectOutputStream(baos);        oos.writeObject(message);        oos.flush();        return baos.toByteArray();    }}

FinalValue

package moremorechat_nio;public final class FinalValue {        public static final int MSG_SYSTEM = 0;        public static final int MSG_GROUP = 1;        public static final int MSG_PRIVATE = 2;        public static final int MSG_ONLINE = 3;        public static final int MSG_NAME = 4;}

Message

package moremorechat_nio;import java.io.Serializable;public class Message implements Serializable {    public int type;    public String message;    public Message() {    }    public Message(String message) {        this.message = message;    }    public Message(int type, String message) {        this.type = type;        this.message = message;    }    @Override    public String toString() {        return "Message{" +                "type=" + type +                ", message='" + message + '\'' +                '}';    }}

NiOServer

package moremorechat_nio;import lombok.extern.slf4j.Slf4j;import java.io.*;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.*;import java.util.ArrayList;import java.util.Iterator;import java.util.Set;import java.util.concurrent.atomic.AtomicBoolean;import java.util.stream.Collectors;import static moremorechat_nio.FinalValue.*;@Slf4jpublic class NioServer {    private Selector selector;    private ServerSocketChannel ssc;    public NioServer() {        try {            // 创建 selector, 管理多个 channel            selector = Selector.open();            //打开ServerSocketChannel,用于监听客户端的连接,它是所有客户端连接的父通道            ssc = ServerSocketChannel.open();            ssc.bind(new InetSocketAddress(8888));            //设置连接为非堵塞模式            ssc.configureBlocking(false);            // 2. 建立 selector 和 channel 的联系(注册)            // SelectionKey 就是将来事件发生后,通过它可以知道事件和哪个channel的事件            //将ServerSocketChannel注册到Reactor线程的多路复用器Selector上,监听ACCEPT事件            ssc.reGISter(selector, SelectionKey.OP_ACCEPT);        } catch (IOException e) {            e.printStackTrace();        }    }    public static void main(String[] args) {        NioServer server = new NioServer();        log.debug("server启动完成,等待用户连接...");        try {            server.listen();        } catch (Exception e) {            log.debug("发生了一些问题");        }    }        private void listen() throws Exception {        while (true) {            // select 方法, 没有事件发生,线程阻塞,有事件,线程才会恢复运行, 通过Selector的select()方法可以选择已经准备就绪的通道 (这些通道包含你感兴趣的的事件)            //通过Selector的select()方法可以选择已经准备就绪的通道 (这些通道包含你感兴趣的的事件)            // select 在事件未处理时,它不会阻塞, 事件发生后要么处理,要么取消,不能置之不理            selector.select();            // 处理事件, selectedKeys 内部包含了所有发生的事件            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();            while (iterator.hasNext()) {                SelectionKey key = iterator.next();                // 处理key 时,要从 selectedKeys 集合中删除,否则下次处理就会有问题                iterator.remove();                // 区分事件类型                if (key.isAcceptable()) {                    ServerSocketChannel channel = (ServerSocketChannel) key.channel();                    SocketChannel sc = channel.accept();                    sc.configureBlocking(false);                    sc.register(selector, SelectionKey.OP_READ);                } else if (key.isReadable()) {                    dealReadEvent(key);                }            }        }    }        private void dealReadEvent(SelectionKey key) {        SocketChannel channel = null;        try {            channel = (SocketChannel) key.channel();            ByteBuffer buffer = ByteBuffer.allocate(1024);            int read = channel.read(buffer);            // 如果是正常断开,read 的方法的返回值是 -1            if (read == -1) {                //cancel 会取消注册在 selector 上的 channel,并从 keys 集合中删除 key 后续不会再监听事件                key.cancel();            } else {                buffer.flip();                Message msg = Utils.decode(buffer.array());                log.debug(msg.toString());                dealMessage(msg, key, channel);            }        } catch (IOException | ClassNotFoundException e) {            System.out.println((key.attachment() == null ? "匿名用户" : key.attachment()) + " 离线了..");            dealMessage(new Message(MSG_SYSTEM, key.attachment() + " 离线了.."), key, channel);            //取消注册            key.cancel();            //关闭通道            try {                channel.close();            } catch (IOException ioException) {                ioException.printStackTrace();            }        }    }        private void dealMessage(Message msg, SelectionKey key, SocketChannel channel) {        switch (msg.type) {            case MSG_NAME:                key.attach(msg.message);                log.debug("用户{}已上线", msg.message);                getConnectedChannel(channel).forEach(selectionKey -> {                    SocketChannel sc = (SocketChannel) selectionKey.channel();                    sendMsgToClient(new Message("收到一条系统消息: " + msg.message + "已上线"), sc);                });                break;            case MSG_GROUP:                getConnectedChannel(channel).forEach(selectionKey -> {                    SocketChannel sc = (SocketChannel) selectionKey.channel();                    sendMsgToClient(new Message(key.attachment() + "给大家发送了一条消息: " + msg.message), sc);                });                break;            case MSG_PRIVATE:                String[] s = msg.message.split("_");                AtomicBoolean flag = new AtomicBoolean(false);                getConnectedChannel(channel).stream().filter(sk -> s[0].equals(sk.attachment())).forEach(selectionKey -> {                    SocketChannel sc = (SocketChannel) selectionKey.channel();                    sendMsgToClient(new Message(key.attachment() + "给你发送了一条消息: " + s[1]), sc);                    flag.set(true);                });                if (!flag.get()){                    sendMsgToClient(new Message(s[1]+"用户不存在,请重新输入!!!"), channel);                }                break;            case MSG_ONLINE:                ArrayList<String> onlineList = new ArrayList<>();                onlineList.add((String) key.attachment());                getConnectedChannel(channel).forEach(selectionKey -> onlineList.add((String) selectionKey.attachment()));                sendMsgToClient(new Message(onlineList.toString()), channel);                break;            case MSG_SYSTEM:                getConnectedChannel(channel).forEach(selectionKey -> {                    SocketChannel sc = (SocketChannel) selectionKey.channel();                    sendMsgToClient(new Message("收到一条系统消息: " + msg.message), sc);                });                break;            default:                break;        }    }        private void sendMsgToClient(Message msg, SocketChannel sc) {        try {            byte[] bytes = Utils.encode(msg);            sc.write(ByteBuffer.wrap(bytes));        } catch (IOException e) {            log.debug("sendMsgToClient出现了一些问题");        }    }        private Set<SelectionKey> getConnectedChannel(SocketChannel channel) {        return selector.keys().stream()                .filter(item -> item.channel() instanceof SocketChannel && item.channel().isOpen() && item.channel() != channel)                .collect(Collectors.toSet());    }}

Nioclient

package moremorechat_nio;import lombok.extern.slf4j.Slf4j;import java.io.*;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 static moremorechat_nio.FinalValue.*;@Slf4jpublic class NioClient {    private Selector selector;    private SocketChannel socketChannel;    private String username;    private static Scanner input;    public NioClient() throws IOException {        selector = Selector.open();        socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8888));        socketChannel.configureBlocking(false);        socketChannel.register(selector, SelectionKey.OP_READ);        log.debug("client启动完成......");        log.debug("请输入你的名字完成注册");        input = new Scanner(System.in);        username = input.next();        log.debug("欢迎{}来到聊天系统", username);    }    public static void main(String[] args) throws IOException {        System.out.println("tips: \n1. 直接发送消息会发给当前的所有用户 \n2. @用户名:消息  会私发给你要发送的用户 \n3. 输入  查询在线用户  会显示当前的在线用户");        NioClient client = new NioClient();        //启动一个子线程接受服务器发送过来的消息        new Thread(() -> {            try {                client.acceptMessageFromServer();            } catch (Exception e) {                e.printStackTrace();            }        }, "receiveClientThread").start();        //调用sendMessageToServer,发送消息到服务端        client.sendMessageToServer();    }        private void sendMessageToServer() throws IOException {        //先把用户名发给客户端        Message message = new Message(MSG_NAME, username);        byte[] bytes = Utils.encode(message);        socketChannel.write(ByteBuffer.wrap(bytes));        while (input.hasNextLine()) {            String msgStr = input.next();            Message msg;            boolean isPrivate = msgStr.startsWith("@");            if (isPrivate) {                int idx = msgStr.indexOf(":");                String targetName = msgStr.substring(1, idx);                msgStr = msgStr.substring(idx + 1);                msg = new Message(MSG_PRIVATE, targetName + "_" + msgStr);            } else if ("查询在线用户".equals(msgStr)) {                msg = new Message(MSG_ONLINE, "请求在线人数");            } else {                msg = new Message(MSG_GROUP, msgStr);            }            byte[] bytes1 = Utils.encode(msg);            socketChannel.write(ByteBuffer.wrap(bytes1));        }    }        private void acceptMessageFromServer() throws Exception {        while (selector.select() > 0) {            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();            while (iterator.hasNext()) {                SelectionKey key = iterator.next();                iterator.remove();                if (key.isReadable()) {                    SocketChannel sc = (SocketChannel) key.channel();                    ByteBuffer buffer = ByteBuffer.allocate(1024);                    sc.read(buffer);                    Message message = Utils.decode(buffer.array());                    log.debug(String.valueOf(message.message));                }            }        }    }}

java基本数据类型有哪些

Java的基本数据类型分为:1、整数类型,用来表示整数的数据类型。2、浮点类型,用来表示小数的数据类型。3、字符类型,字符类型的关键字是“char”。4、布尔类型,是表示逻辑值的基本数据类型。

感谢各位的阅读!关于“Java怎么实现NIO聊天室”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: Java怎么实现NIO聊天室

本文链接: https://www.lsjlt.com/news/276358.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java怎么实现NIO聊天室
    这篇文章给大家分享的是有关Java怎么实现NIO聊天室的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。功能介绍功能:群聊+私发+上线提醒+下线提醒+查询在线用户文件Utils需要用maven导入下面两个包 ...
    99+
    2023-06-15
  • Java NIO怎么实现聊天室功能
    这篇文章主要介绍了Java NIO怎么实现聊天室功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。具体内容如下代码里面已经包含了必要的注释,这里不详述了。实现了基本...
    99+
    2023-06-21
  • Java NIO怎么实现聊天室程序
    本文小编为大家详细介绍“Java NIO怎么实现聊天室程序”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java NIO怎么实现聊天室程序”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。服务端:package&n...
    99+
    2023-06-17
  • Java NIO实现聊天室功能
    本文实例为大家分享了Java NIO实现聊天室功能的具体代码,供大家参考,具体内容如下 代码里面已经包含了必要的注释,这里不详述了。实现了基本的聊天室功能。 常量类: publi...
    99+
    2022-11-12
  • Java NIO实现多人聊天室
    本文实例为大家分享了Java NIO实现多人聊天室的具体代码,供大家参考,具体内容如下 1. 服务器端代码 ChatServer类: package nio.test.serve...
    99+
    2022-11-12
  • Java基于NIO怎么实现聊天室功能
    Java基于NIO怎么实现聊天室功能,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Sever端package com.qst.one;import java...
    99+
    2023-06-21
  • 怎么使用Java NIO实现多人聊天室
    本篇内容主要讲解“怎么使用Java NIO实现多人聊天室”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用Java NIO实现多人聊天室”吧!NIO服务端public&n...
    99+
    2023-06-21
  • Java基于NIO实现聊天室功能
    本文实例为大家分享了Java基于NIO实现聊天室功能的具体代码,供大家参考,具体内容如下 Sever端 package com.qst.one; import java.io....
    99+
    2022-11-12
  • Java NIO实战之多人聊天室
    本文实例为大家分享了Java NIO实战之多人聊天室的具体代码,供大家参考,具体内容如下 NIO服务端 public class NioServer { pu...
    99+
    2022-11-12
  • Java实现NIO聊天室的示例代码(群聊+私聊)
    目录功能介绍文件UtilsFinalValueMessageNioServerNioClient功能介绍 功能:群聊+私发+上线提醒+下线提醒+查询在线用户 文件 U...
    99+
    2022-11-12
  • Java聊天室之实现聊天室服务端功能
    目录一、题目描述二、解题思路三、代码详解多学一个知识点一、题目描述 题目实现:实现聊天室服务器端功能。运行程序,服务端等待客户端连接,并显示客户端的连接信息。 二、解题思路 创建一个...
    99+
    2022-11-13
    Java实现聊天室 Java 聊天室 Java 服务端
  • Java聊天室之实现聊天室客户端功能
    目录一、题目描述二、解题思路三、代码详解一、题目描述 题目实现:实现聊天室客户端。运行程序,用户登录服务器后,可以从用户列表中选择单个用户进行聊天,也可以选择多个用户进行聊天。 二、...
    99+
    2022-11-13
    Java实现聊天室 Java 聊天室 Java 客户端
  • Java实现聊天室界面
    本文实例为大家分享了Java实现聊天室界面的具体代码,供大家参考,具体内容如下 服务器端: package Server;   import java.awt.Toolkit; im...
    99+
    2022-11-13
  • Java NIO实现聊天功能
    本文实例为大家分享了Java NIO实现聊天功能的具体代码,供大家参考,具体内容如下 server code :  package com.tch.test.nio; imp...
    99+
    2022-11-12
  • Java NIO实现聊天系统
    使用Java的NIO写的一个小的聊天系统,供大家参考,具体内容如下 一、服务端 public class GroupChatServer { // 定义相关的属性 ...
    99+
    2022-11-12
  • java怎么实现多人聊天对话室
    这篇文章给大家分享的是有关java怎么实现多人聊天对话室的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。使用ServerSocket和Socket实现服务器端和客户端的Socket通信。了解完socket通信步骤后...
    99+
    2023-06-20
  • java NIO怎么实现简单聊天程序
    这篇文章主要为大家展示了“java NIO怎么实现简单聊天程序”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“java NIO怎么实现简单聊天程序”这篇文章吧。具体内容如下服务...
    99+
    2023-06-21
  • Java Socket实现简易聊天室
    Java-Socket编程实现简易聊天室(TCP),供大家参考,具体内容如下 实现一个服务器接收多个客户端 测试: 首先启动服务器,然后启动三个客户端,输入三个不同的用户名,分别在聊...
    99+
    2022-11-11
  • Java Socket模拟实现聊天室
    使用Java Socket模拟实现了一个聊天室,实现了基本的私聊以及群聊。分为服务器端和客户端,下面我来介绍一下实现的步骤。 服务器端 服务器端是聊天室的核心所在,主要用来处理客户端...
    99+
    2022-11-12
  • Java实现单线程聊天室
    本文实例为大家分享了Java实现单线程聊天室的具体代码,供大家参考,具体内容如下 一. Socket API简介 1. Socket编程 Java.net.Socket类代表一个套接...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作