欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java?NIO實現(xiàn)聊天系統(tǒng)

 更新時間:2021年11月24日 12:11:49   作者:菜鳥程序猿進階之路  
這篇文章主要為大家詳細介紹了Java?NIO實現(xiàn)聊天系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

使用Java的NIO寫的一個小的聊天系統(tǒng),供大家參考,具體內容如下

一、服務端

/**
 * 群聊的服端
 *
 * @author :breakpoint/趙立剛
 * @date : 2020/08/13
 */
public class GroupChatServer {

    // 定義相關的屬性
    private Selector selector;
    private ServerSocketChannel listenChannel;
    private static final int port = 6667;

    // 構造器
    // 進行初始化的操作
    public GroupChatServer() {
        try {
            // 獲取選擇器
            selector = Selector.open();
            // 獲取到 listenChannel
            listenChannel = ServerSocketChannel.open();
            // 設定端口
            listenChannel.bind(new InetSocketAddress(port));
            // 設定非阻塞模式
            listenChannel.configureBlocking(false);
            // 將該 listenChannel 注冊到 selector上 完成操作
            listenChannel.register(selector, SelectionKey.OP_ACCEPT);
            System.out.println("服務器啟動了。。。。");
        } catch (IOException e) {

        }

    }

    // 監(jiān)聽的代碼

    public void listen() {
        try {
            // 循環(huán)處理
            while (true) {
                int count = selector.select(2000);
                if (count > 0) {
                    // 有事件需要處理
                    // 遍歷處理 得到selectionKeys集合
                    Set<SelectionKey> selectionKeys = selector.selectedKeys();
                    Iterator<SelectionKey> selectionKeyIterator = selectionKeys.iterator();
                    while (selectionKeyIterator.hasNext()) {
                        // 得到selectionKey
                        SelectionKey selectionKey = selectionKeyIterator.next();
                        // 監(jiān)聽到了 accept
                        if (selectionKey.isAcceptable()) {
                            // 獲取到連接
                            SocketChannel sc = listenChannel.accept();
                            sc.configureBlocking(false);
                            sc.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));
                            // 提示上線
                            System.out.println(sc.getRemoteAddress() + ":上線啦。。。。");
                        }

                        if (selectionKey.isReadable()) {
                            // 讀取事件 通道是可以讀的狀態(tài) //專門寫
                            readData(selectionKey);
                        }


                        // 移除當前的刪除 防止重復處理操作
                        selectionKeyIterator.remove();
                    }


                } else {
                    System.out.println("等待中。。。。。。");
                }
            }

        } catch (Exception e) {

        } finally {

        }
    }

    // 讀取客戶端的消息

    private void readData(SelectionKey selectionKey) {
        // 獲取 socketChannel

        SocketChannel channel = null;
        try {
            channel = (SocketChannel) selectionKey.channel();
            ByteBuffer byteBuffer = (ByteBuffer) selectionKey.attachment();
            int count = channel.read(byteBuffer);
            // 分情況處理
            if (count > 0) {
                // 獲取到數(shù)據(jù)專程
                String msg = new String(byteBuffer.array(), 0, count);
                byteBuffer.clear();
                System.out.println(channel.getRemoteAddress() + "來自客戶端" + msg);
                // 向其他的客戶端轉發(fā)消息
                sendInfoToOtherClients(msg, channel);
            }

        } catch (IOException e) {
            // 如果發(fā)生異常 提示說明離線了
            try {
                System.out.println(channel.getRemoteAddress() + "離線了。。。。");
                // 取消注冊
                selectionKey.cancel();
                // 關閉通道
                channel.close();
            } catch (IOException e1) {
                //e1.printStackTrace();
            }
        } finally {

        }
    }


    // 轉發(fā)消息給其他的客戶端 去掉自己的客戶端
    private void sendInfoToOtherClients(String msg, SocketChannel self) throws IOException {
        System.out.println("服務器轉發(fā)消息。。。。。");
        // 進行遍歷操作
        Set<SelectionKey> keys = selector.keys();
        for (SelectionKey key : keys) {
            // 取出來所有的
            Channel targetChannel = key.channel();
            // 排除自己
            if (targetChannel instanceof SocketChannel && targetChannel != self) {
                SocketChannel dest = (SocketChannel) targetChannel;
                ByteBuffer byteBuffer = ByteBuffer.wrap(msg.getBytes());
                // 發(fā)送數(shù)據(jù)
                dest.write(byteBuffer);
            }
        }
    }


    public static void main(String[] args) {
        GroupChatServer groupChatServer = new GroupChatServer();
        groupChatServer.listen();
    }
}

二、客戶端代碼

/**
 * @author :breakpoint/趙立剛
 * @date : 2020/08/13
 */
public class GroupChatClient {

    // 定義相關屬性

    private final String HOST = "127.0.0.1"; //服務器地址
    private final int port = 6667; // 服務器端口
    private Selector selector;
    private SocketChannel socketChannel;
    private String userName;

    // 完成初始化工作
    public GroupChatClient() {
        try {
            selector = Selector.open();
            // 連接服務器
            socketChannel = SocketChannel.open(new InetSocketAddress(HOST, port));
            // 設置非阻塞工作
            socketChannel.configureBlocking(false);
            // 注冊我們的通道
            socketChannel.register(selector, SelectionKey.OP_READ);
            userName = socketChannel.getLocalAddress().toString();
            System.out.println("客戶端專備好啦");
        } catch (IOException e) {

        }
    }

    public void sendInfo(String info) {
        String msg = userName + "說:" + info;
        try {
            ByteBuffer wrap = ByteBuffer.wrap(msg.getBytes());
            socketChannel.write(wrap);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 讀取信息
    public void readInfo() {
        try {
            int readChannel = selector.select(2000);
            if (readChannel > 0) {
                // 有可以用的通道
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> iterator = selectionKeys.iterator();
                while (iterator.hasNext()) {
                    SelectionKey next = iterator.next();
                    if (next.isReadable()) {
                        SelectableChannel keyChannel = next.channel();
                        if (keyChannel instanceof SocketChannel) {
                            // 獲取到我們的通道
                            SocketChannel channel = (SocketChannel) keyChannel;
                            ByteBuffer allocate = ByteBuffer.allocate(1024);
                            // 讀取數(shù)據(jù)
                            int read = channel.read(allocate);
                            if (read > 0) {
                                // 輸出我們的消息
                                System.out.println(new String(allocate.array(), 0, read));
                            }

                        }// end if
                    }
                    iterator.remove();
                }
            } else {
                System.out.println("沒有可用的通道");
            }
        } catch (IOException e) {

        }
    }

    public static void main(String[] args) throws Exception {


        // 啟動客戶端的操作
        final GroupChatClient groupChatClient = new GroupChatClient();


        // 啟動一個線程

        new Thread(() -> {
            while (true) {
                groupChatClient.readInfo();
                try {
                    Thread.currentThread().sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();


        Scanner scanner = new Scanner(System.in);

        while (scanner.hasNext()) {
            // 輸入信息
            String s = scanner.nextLine();
            groupChatClient.sendInfo(s);
        }


        System.in.read();
    }
}

三、運行的結果

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。?

相關文章

  • java開發(fā)MVC三層架構上再加一層Manager層原理詳解

    java開發(fā)MVC三層架構上再加一層Manager層原理詳解

    這篇文章主要為大家介紹了MVC三層架構中再加一層Manager層原理的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2021-10-10
  • java實現(xiàn)手機短信驗證的基本思路

    java實現(xiàn)手機短信驗證的基本思路

    這篇文章主要為大家詳細介紹了java實現(xiàn)手機短信驗證的基本思路,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • 詳解Java中Math.round()的取整規(guī)則

    詳解Java中Math.round()的取整規(guī)則

    這篇文章主要介紹了詳解Java中Math.round()的取整規(guī)則,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-05-05
  • Java嵌套類和內部類詳解

    Java嵌套類和內部類詳解

    這篇文章主要介紹了Java嵌套類和內部類詳解,本文講解了什么是嵌套類及內部類、靜態(tài)嵌套類、在外部類中定義內部類、在方法中定義內部類、匿名內部類等內容,需要的朋友可以參考下
    2015-04-04
  • JAVA8之函數(shù)式編程Function接口用法

    JAVA8之函數(shù)式編程Function接口用法

    這篇文章主要介紹了JAVA8之函數(shù)式編程Function接口用法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Java中static修飾的靜態(tài)變量、方法及代碼塊的特性與使用

    Java中static修飾的靜態(tài)變量、方法及代碼塊的特性與使用

    這篇文章主要介紹了Java中static修飾的靜態(tài)變量、方法及代碼塊的特性與使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • Java設計模式之責任鏈模式

    Java設計模式之責任鏈模式

    今天小編就為大家分享一篇關于Java設計模式之責任鏈模式,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • 基于JAVA中Jersey處理Http協(xié)議中的Multipart的詳解

    基于JAVA中Jersey處理Http協(xié)議中的Multipart的詳解

    之前在基于C#開發(fā)彩信用最原始的StringBuilder拼接字符串方式處理過Multipart?,F(xiàn)在在做一個項目的時候,由于之前的技術路線都是使用Jersey處理Http這塊,為了保持技術路線一致,研究了一下如何使用Jersey處理Http協(xié)議中的Multipart
    2013-05-05
  • shiro編碼和加密代碼詳解

    shiro編碼和加密代碼詳解

    Shiro提供了base64和16進制字符串編碼/解碼的API支持,方便一些編碼解碼操作。下面通過實例代碼給大家詳解shiro編碼和加密知識,感興趣的朋友一起看看吧
    2017-09-09
  • SpringBoot+RabbitMq具體使用的幾種姿勢

    SpringBoot+RabbitMq具體使用的幾種姿勢

    這篇文章主要介紹了SpringBoot+RabbitMq具體使用的幾種姿勢,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-05-05

最新評論