最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

全球今日报丨Java 基础 -- NIO 多人聊天室

来源:博客园


(资料图片仅供参考)

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();            //ServerSocketChannel            listenChannel =  ServerSocketChannel.open();            //绑定端口            listenChannel.socket().bind(new InetSocketAddress(PORT));            //设置非阻塞模式            listenChannel.configureBlocking(false);            //将该listenChannel 注册到selector            listenChannel.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 iterator = selector.selectedKeys().iterator();                    while (iterator.hasNext()) {                        //取出selectionkey                        SelectionKey key = iterator.next();                        //监听到accept                        if(key.isAcceptable()) {                            SocketChannel sc = listenChannel.accept();                            sc.configureBlocking(false);                            //将该 sc 注册到seletor                            sc.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) {        //取到关联的channle        SocketChannel channel = null;        try {           //得到channel            channel = (SocketChannel) key.channel();            //创建buffer            ByteBuffer 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,并排除 self        for(SelectionKey key: selector.keys()) {            //通过 key  取出对应的 SocketChannel            Channel targetChannel = key.channel();            //排除自己            if(targetChannel instanceof  SocketChannel && targetChannel != self) {                //转型                SocketChannel dest = (SocketChannel)targetChannel;                //将msg 存储到buffer                ByteBuffer buffer = ByteBuffer.wrap(msg.getBytes());                //将buffer 的数据写入 通道                dest.write(buffer);            }        }    }    public static void main(String[] args) {        //创建服务器对象        GroupChatServer groupChatServer = new GroupChatServer();        groupChatServer.listen();    }}//可以写一个Handlerclass MyHandler {    public void readData() {    }    public void sendInfoToOtherClients(){    }}
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"; // 服务器的ip    private 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 注册到selector        socketChannel.register(selector, SelectionKey.OP_READ);        //得到username        username = 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 iterator = selector.selectedKeys().iterator();                while (iterator.hasNext()) {                    SelectionKey key = iterator.next();                    if(key.isReadable()) {                        //得到相关的通道                       SocketChannel sc = (SocketChannel) key.channel();                       //得到一个Buffer                        ByteBuffer 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);        }    }}

关键词: