欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java基于NIO实现群聊功能

程序员文章站 2022-03-15 19:32:49
本文实例为大家分享了java基于nio实现群聊功能的具体代码,供大家参考,具体内容如下一、群聊服务器package com.dashu.netty.group_chat;import java.net...

本文实例为大家分享了java基于nio实现群聊功能的具体代码,供大家参考,具体内容如下

一、群聊服务器

package com.dashu.netty.group_chat;

import java.net.inetsocketaddress;
import java.nio.bytebuffer;
import java.nio.channels.*;
import java.nio.charset.standardcharsets;
import java.util.iterator;


public class groupchatserver {


    /**
     * 初始化选择器
     */
    private selector selector;

    /**
     * 初始化服务器网络通道
     */
    private serversocketchannel serversocketchannel;

    /**
     * 端口
     */
    private static final int port = 6666;


    /**
     * 构造方法
     */
    public groupchatserver() {

        try {

            //获取选择器
            selector = selector.open();

            //获取服务器网络通道
            serversocketchannel = serversocketchannel.open();

            //网络地址
            inetsocketaddress inetsocketaddress = new inetsocketaddress(port);

            //服务器网络通道绑定网络地址
            serversocketchannel.socket().bind(inetsocketaddress);

            //设置服务器网络通道非阻塞
            serversocketchannel.configureblocking(false);

            //将服务器网络通道注册到选择器上,绑定连接请求事件
            serversocketchannel.register(selector, selectionkey.op_accept);

        } catch (exception e) {

            e.printstacktrace();

        }

    }


    /**
     * 监听客户端请求事件
     */
    public void listen() {


        try {

            //无限循环
            while (true) {

                //获取请求数
                int count = selector.select();

                //count大于0,则代表有请求进来
                if (count > 0) {


                    //获取请求集
                    iterator<selectionkey> selectionkeyiterator = selector.selectedkeys().iterator();

                    //遍历请求集
                    while (selectionkeyiterator.hasnext()) {

                        //得到请求
                        selectionkey selectionkey = selectionkeyiterator.next();

                        //连接请求
                        if (selectionkey.isacceptable()) {

                            //获取客户端网络通道
                            socketchannel socketchannel = serversocketchannel.accept();

                            //设置客户端网络通道非阻塞
                            socketchannel.configureblocking(false);

                            //将客户端网络通道注册到选择器上
                            socketchannel.register(selector, selectionkey.op_read);

                            system.out.println(socketchannel.getremoteaddress() + "上线了");

                        }

                        //信息读取请求
                        if (selectionkey.isreadable()) {

                            //客户端信息读取
                            readdata(selectionkey);

                        }

                        //移除请求
                        selectionkeyiterator.remove();

                    }


                } else {

                    system.out.println("等待...");

                }

            }
        } catch (exception e) {
            e.printstacktrace();
        }

    }


    /**
     * 客户端信息读取
     *
     * @param selectionkey
     */
    private void readdata(selectionkey selectionkey) {

        //初始化客户端网络通道
        socketchannel socketchannel = null;

        try {

            //获取客户端网络通道
            socketchannel = (socketchannel) selectionkey.channel();

            //创建缓冲区
            bytebuffer bytebuffer = bytebuffer.allocate(1024);

            //读取客户端网络通道中的数据到缓冲区
            int count = socketchannel.read(bytebuffer);

            //判断缓冲区中是否有数据
            if (count > 0) {

                //将缓冲区的数据转换位字符串
                string message = new string(bytebuffer.array());

                system.out.println(message.trim());

                //将信息群发到其他客户端
                sendinfotootclients(message, socketchannel);

            }

        } catch (exception e) {

            e.printstacktrace();

        }


    }

    /**
     * 将信息群发到其他客户端
     *
     * @param message
     * @param socketchannel
     */
    private void sendinfotootclients(string message, socketchannel socketchannel) {

        //获取所有注册到选择器的客户端,并遍历
        for (selectionkey selectionkey : selector.keys()) {

            //获取通道
            channel channel = selectionkey.channel();

            //判断通道是否属于socketchannel,同时不等于发送信息的客户端
            if (channel instanceof socketchannel && channel != socketchannel) {

                //通道转换
                socketchannel sc = (socketchannel) channel;

                //将信息写入缓冲区
                bytebuffer bytebuffer = bytebuffer.wrap(message.getbytes(standardcharsets.utf_8));

                try {

                    //将缓冲区的数据写入通道
                    sc.write(bytebuffer);

                } catch (exception e) {

                    e.printstacktrace();

                }

            }

        }

    }




    public static void main(string[] args) {

        groupchatserver groupchatserver = new groupchatserver();

        system.out.println("服务器启动,开始监听客户端请求...");
        groupchatserver.listen();

    }


}

二、客户端

package com.dashu.netty.group_chat;

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.nio.charset.standardcharsets;
import java.util.iterator;
import java.util.scanner;

public class groupchatclient {


    /**
     * 网络连接地址
     */
    private final string host = "127.0.0.1";

    /**
     * 端口
     */
    private final int port = 6666;

    /**
     * 初始化选择器
     */
    private selector selector;

    /**
     * 初始化网络通道
     */
    private socketchannel socketchannel;


    /**
     * 用户名
     */
    private string username;


    public groupchatclient() {
        try {

            //获取选择器
            selector = selector.open();


            //获取服务器网络地址
            inetsocketaddress inetsocketaddress = new inetsocketaddress(host, port);

            //获取网络通道
            socketchannel = socketchannel.open(inetsocketaddress);

            //设置网络通道非阻塞
            socketchannel.configureblocking(false);


            //将网络通道注册到选择器
            socketchannel.register(selector, selectionkey.op_read);


            //获取用户名
            system.out.println("请输入用户名:");

            scanner scanner = new scanner(system.in);

            username = scanner.nextline();

            system.out.println(username + " 进入群聊...");

        } catch (exception e) {

            e.printstacktrace();

        }
    }


    /**
     * 向服务器发送信息
     *
     * @param message
     */
    public void sendinfo(string message) {

        message = username + ":" + message;

        try {

            //向通道写入数据
            socketchannel.write(bytebuffer.wrap(message.getbytes(standardcharsets.utf_8)));

        } catch (exception e) {

            e.printstacktrace();

        }

    }


    /**
     * 读取服务器发来的信息
     */
    public void readinfo() {
        try {

            //获取请求数
            int count = selector.select();

            if (count > 0) {

                //获取请求集
                iterator<selectionkey> selectionkeyiterator = selector.selectedkeys().iterator();

                //遍历请求集
                while (selectionkeyiterator.hasnext()) {

                    //获取请求
                    selectionkey selectionkey = selectionkeyiterator.next();

                    //判断位读请求
                    if (selectionkey.isreadable()) {

                        //获取通道
                        socketchannel sc = (socketchannel) selectionkey.channel();

                        //创建缓冲区
                        bytebuffer bytebuffer = bytebuffer.allocate(1024);


                        //读取通道的数据到缓冲区
                        sc.read(bytebuffer);

                        //缓冲区数据转字符串
                        string message = new string(bytebuffer.array());

                        //输出
                        system.out.println(message.trim());

                    }

                    //移除已完成请求
                    selectionkeyiterator.remove();

                }

            }

        } catch (exception e) {

            e.printstacktrace();

        }


    }


    public static void main(string[] args) {

        groupchatclient groupchatclient = new groupchatclient();

        /**
         * 开启一个线程,每3秒读取一次服务器发来的信息
         */
        new thread() {
            @override
            public void run() {
                while (true) {
                    groupchatclient.readinfo();
                    try {
                        thread.sleep(3000);
                    } catch (exception e) {
                        e.printstacktrace();
                    }
                }
            }
        }.start();


        //信息输入
        scanner scanner = new scanner(system.in);

        system.out.println("请输入信息:");
        while (scanner.hasnextline()) {

            string s = scanner.nextline();

            //信息发送
            groupchatclient.sendinfo(s);

            system.out.println("请输入信息:");

        }
    }


}

三、效果图

1、服务器

Java基于NIO实现群聊功能

2、客户端01

Java基于NIO实现群聊功能

3、客户端02

Java基于NIO实现群聊功能

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

相关标签: Java NIO 群聊