最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java基于NIO實(shí)現(xiàn)群聊功能

 更新時(shí)間:2021年11月23日 17:15:19   作者:大樹下躲雨  
這篇文章主要為大家詳細(xì)介紹了Java基于NIO實(shí)現(xiàn)群聊功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了Java基于NIO實(shí)現(xiàn)群聊功能的具體代碼,供大家參考,具體內(nèi)容如下

一、群聊服務(wù)器

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;

    /**
     * 初始化服務(wù)器網(wǎng)絡(luò)通道
     */
    private ServerSocketChannel serverSocketChannel;

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


    /**
     * 構(gòu)造方法
     */
    public GroupChatServer() {

        try {

            //獲取選擇器
            selector = Selector.open();

            //獲取服務(wù)器網(wǎng)絡(luò)通道
            serverSocketChannel = ServerSocketChannel.open();

            //網(wǎng)絡(luò)地址
            InetSocketAddress inetSocketAddress = new InetSocketAddress(PORT);

            //服務(wù)器網(wǎng)絡(luò)通道綁定網(wǎng)絡(luò)地址
            serverSocketChannel.socket().bind(inetSocketAddress);

            //設(shè)置服務(wù)器網(wǎng)絡(luò)通道非阻塞
            serverSocketChannel.configureBlocking(false);

            //將服務(wù)器網(wǎng)絡(luò)通道注冊(cè)到選擇器上,綁定連接請(qǐng)求事件
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }


    /**
     * 監(jiān)聽客戶端請(qǐng)求事件
     */
    public void listen() {


        try {

            //無限循環(huán)
            while (true) {

                //獲取請(qǐng)求數(shù)
                int count = selector.select();

                //count大于0,則代表有請(qǐng)求進(jìn)來
                if (count > 0) {


                    //獲取請(qǐng)求集
                    Iterator<SelectionKey> selectionKeyIterator = selector.selectedKeys().iterator();

                    //遍歷請(qǐng)求集
                    while (selectionKeyIterator.hasNext()) {

                        //得到請(qǐng)求
                        SelectionKey selectionKey = selectionKeyIterator.next();

                        //連接請(qǐng)求
                        if (selectionKey.isAcceptable()) {

                            //獲取客戶端網(wǎng)絡(luò)通道
                            SocketChannel socketChannel = serverSocketChannel.accept();

                            //設(shè)置客戶端網(wǎng)絡(luò)通道非阻塞
                            socketChannel.configureBlocking(false);

                            //將客戶端網(wǎng)絡(luò)通道注冊(cè)到選擇器上
                            socketChannel.register(selector, SelectionKey.OP_READ);

                            System.out.println(socketChannel.getRemoteAddress() + "上線了");

                        }

                        //信息讀取請(qǐng)求
                        if (selectionKey.isReadable()) {

                            //客戶端信息讀取
                            readData(selectionKey);

                        }

                        //移除請(qǐng)求
                        selectionKeyIterator.remove();

                    }


                } else {

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

                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    /**
     * 客戶端信息讀取
     *
     * @param selectionKey
     */
    private void readData(SelectionKey selectionKey) {

        //初始化客戶端網(wǎng)絡(luò)通道
        SocketChannel socketChannel = null;

        try {

            //獲取客戶端網(wǎng)絡(luò)通道
            socketChannel = (SocketChannel) selectionKey.channel();

            //創(chuàng)建緩沖區(qū)
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

            //讀取客戶端網(wǎng)絡(luò)通道中的數(shù)據(jù)到緩沖區(qū)
            int count = socketChannel.read(byteBuffer);

            //判斷緩沖區(qū)中是否有數(shù)據(jù)
            if (count > 0) {

                //將緩沖區(qū)的數(shù)據(jù)轉(zhuǎn)換位字符串
                String message = new String(byteBuffer.array());

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

                //將信息群發(fā)到其他客戶端
                sendInfoToOtClients(message, socketChannel);

            }

        } catch (Exception e) {

            e.printStackTrace();

        }


    }

    /**
     * 將信息群發(fā)到其他客戶端
     *
     * @param message
     * @param socketChannel
     */
    private void sendInfoToOtClients(String message, SocketChannel socketChannel) {

        //獲取所有注冊(cè)到選擇器的客戶端,并遍歷
        for (SelectionKey selectionKey : selector.keys()) {

            //獲取通道
            Channel channel = selectionKey.channel();

            //判斷通道是否屬于SocketChannel,同時(shí)不等于發(fā)送信息的客戶端
            if (channel instanceof SocketChannel && channel != socketChannel) {

                //通道轉(zhuǎn)換
                SocketChannel sc = (SocketChannel) channel;

                //將信息寫入緩沖區(qū)
                ByteBuffer byteBuffer = ByteBuffer.wrap(message.getBytes(StandardCharsets.UTF_8));

                try {

                    //將緩沖區(qū)的數(shù)據(jù)寫入通道
                    sc.write(byteBuffer);

                } catch (Exception e) {

                    e.printStackTrace();

                }

            }

        }

    }




    public static void main(String[] args) {

        GroupChatServer groupChatServer = new GroupChatServer();

        System.out.println("服務(wù)器啟動(dòng),開始監(jiān)聽客戶端請(qǐng)求...");
        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 {


    /**
     * 網(wǎng)絡(luò)連接地址
     */
    private final String HOST = "127.0.0.1";

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

    /**
     * 初始化選擇器
     */
    private Selector selector;

    /**
     * 初始化網(wǎng)絡(luò)通道
     */
    private SocketChannel socketChannel;


    /**
     * 用戶名
     */
    private String username;


    public GroupChatClient() {
        try {

            //獲取選擇器
            selector = Selector.open();


            //獲取服務(wù)器網(wǎng)絡(luò)地址
            InetSocketAddress inetSocketAddress = new InetSocketAddress(HOST, PORT);

            //獲取網(wǎng)絡(luò)通道
            socketChannel = SocketChannel.open(inetSocketAddress);

            //設(shè)置網(wǎng)絡(luò)通道非阻塞
            socketChannel.configureBlocking(false);


            //將網(wǎng)絡(luò)通道注冊(cè)到選擇器
            socketChannel.register(selector, SelectionKey.OP_READ);


            //獲取用戶名
            System.out.println("請(qǐng)輸入用戶名:");

            Scanner scanner = new Scanner(System.in);

            username = scanner.nextLine();

            System.out.println(username + " 進(jìn)入群聊...");

        } catch (Exception e) {

            e.printStackTrace();

        }
    }


    /**
     * 向服務(wù)器發(fā)送信息
     *
     * @param message
     */
    public void sendInfo(String message) {

        message = username + ":" + message;

        try {

            //向通道寫入數(shù)據(jù)
            socketChannel.write(ByteBuffer.wrap(message.getBytes(StandardCharsets.UTF_8)));

        } catch (Exception e) {

            e.printStackTrace();

        }

    }


    /**
     * 讀取服務(wù)器發(fā)來的信息
     */
    public void readInfo() {
        try {

            //獲取請(qǐng)求數(shù)
            int count = selector.select();

            if (count > 0) {

                //獲取請(qǐng)求集
                Iterator<SelectionKey> selectionKeyIterator = selector.selectedKeys().iterator();

                //遍歷請(qǐng)求集
                while (selectionKeyIterator.hasNext()) {

                    //獲取請(qǐng)求
                    SelectionKey selectionKey = selectionKeyIterator.next();

                    //判斷位讀請(qǐng)求
                    if (selectionKey.isReadable()) {

                        //獲取通道
                        SocketChannel sc = (SocketChannel) selectionKey.channel();

                        //創(chuàng)建緩沖區(qū)
                        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);


                        //讀取通道的數(shù)據(jù)到緩沖區(qū)
                        sc.read(byteBuffer);

                        //緩沖區(qū)數(shù)據(jù)轉(zhuǎn)字符串
                        String message = new String(byteBuffer.array());

                        //輸出
                        System.out.println(message.trim());

                    }

                    //移除已完成請(qǐng)求
                    selectionKeyIterator.remove();

                }

            }

        } catch (Exception e) {

            e.printStackTrace();

        }


    }


    public static void main(String[] args) {

        GroupChatClient groupChatClient = new GroupChatClient();

        /**
         * 開啟一個(gè)線程,每3秒讀取一次服務(wù)器發(fā)來的信息
         */
        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("請(qǐng)輸入信息:");
        while (scanner.hasNextLine()) {

            String s = scanner.nextLine();

            //信息發(fā)送
            groupChatClient.sendInfo(s);

            System.out.println("請(qǐng)輸入信息:");

        }
    }


}

三、效果圖

1、服務(wù)器

2、客戶端01

3、客戶端02

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Spring生命周期回調(diào)與容器擴(kuò)展詳解

    Spring生命周期回調(diào)與容器擴(kuò)展詳解

    這篇文章主要介紹了Spring生命周期回調(diào)與容器擴(kuò)展詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Spring框架基于AOP實(shí)現(xiàn)簡(jiǎn)單日志管理步驟解析

    Spring框架基于AOP實(shí)現(xiàn)簡(jiǎn)單日志管理步驟解析

    這篇文章主要介紹了Spring框架基于AOP實(shí)現(xiàn)簡(jiǎn)單日志管理步驟解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • 詳解@Autowired是如何注入變量的

    詳解@Autowired是如何注入變量的

    在?Spring?容器中,當(dāng)我們想給某一個(gè)屬性注入值的時(shí)候,有多種不同的方式,例如使用?@Autowired、@Inject等注解,下面小編就來和小伙伴們聊一聊,@Autowired?到底是如何把數(shù)據(jù)注入進(jìn)來的
    2023-07-07
  • Java?Thread.currentThread().getName()?和?this.getName()區(qū)別詳解

    Java?Thread.currentThread().getName()?和?this.getName()區(qū)別詳

    本文主要介紹了Thread.currentThread().getName()?和?this.getName()區(qū)別詳解,TestThread?testThread?=?new?TestThread();
    2022-02-02
  • 詳解netty中的frame解碼器

    詳解netty中的frame解碼器

    netty為我們提供了一些合適的frame解碼器,通過使用這些frame解碼器可以有效的簡(jiǎn)化我們的工作,這篇文章主要介紹了netty中的frame解碼器,需要的朋友可以參考下
    2022-04-04
  • SpringBoot?替換?if?的參數(shù)校驗(yàn)示例代碼

    SpringBoot?替換?if?的參數(shù)校驗(yàn)示例代碼

    Spring?Validation是對(duì)hibernate?validation的二次封裝,用于支持spring?mvc參數(shù)自動(dòng)校驗(yàn),接下來,我們以spring-boot項(xiàng)目為例,介紹Spring?Validation的使用,需要的朋友可以參考下
    2022-12-12
  • JavaWeb搭建網(wǎng)上圖書商城畢業(yè)設(shè)計(jì)

    JavaWeb搭建網(wǎng)上圖書商城畢業(yè)設(shè)計(jì)

    這篇文章主要介紹了JavaWeb搭建網(wǎng)上圖書商城框架,特別適合正在為網(wǎng)上商城畢業(yè)設(shè)計(jì)煩惱的同學(xué),需要的朋友可以參考下
    2015-11-11
  • 一篇文章帶你了解Spring?AOP?的注解

    一篇文章帶你了解Spring?AOP?的注解

    這篇文章主要為大家介紹了vue組件通信的幾種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • 最新評(píng)論

    蒲江县| 绥棱县| 枝江市| 江陵县| 新津县| 齐河县| 庆云县| 永修县| 林州市| 开鲁县| 阜新市| 南开区| 西峡县| 河间市| 安仁县| 雷波县| 玉门市| 吉木乃县| 永州市| 塔城市| 乌什县| 抚远县| 兴山县| 平舆县| 吉安市| 天长市| 政和县| 剑阁县| 蒙城县| 将乐县| 五寨县| 库尔勒市| 明光市| 兴义市| 台前县| 红安县| 阿瓦提县| 拜城县| 绥芬河市| 客服| 临泉县|