java NIO实现简单聊天程序

 更新时间:2021年11月24日 09:41:46   作者:iRich_全栈  
这篇文章主要为大家详细介绍了java NIO实现简单聊天程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了java NIO实现简单聊天程序的具体代码,供大家参考,具体内容如下

服务端

功能:

1、接受客户端连接
2、发送消息
3、读取客户端消息

Server.java

public class Server {

    private Selector selector;
    private ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
    private ByteBuffer readBuffer = ByteBuffer.allocate(1024);
    Msg msg = new Msg();
    MsgSender msgSender = new MsgSender(msg);
    public static void main(String[] args) {
        Server server = new Server();
        new Thread(server.msgSender).start();
        server.start();

    }

    //初始化服务端
    public Server() {
        try {
            this.selector = Selector.open();
            ServerSocketChannel ssc = ServerSocketChannel.open();
            ssc.configureBlocking(false);
            ssc.bind(new InetSocketAddress(8899));
            ssc.register(this.selector, SelectionKey.OP_ACCEPT);
            System.out.println("服务端初始化完毕。。。。");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //启动服务端等待selector事件
    public void start() {
        while (true) {
            try {
                int num = this.selector.select();
                if (num > 0) {
                    Iterator<SelectionKey> it = this.selector.selectedKeys().iterator();
                    while (it.hasNext()) {
                        SelectionKey key = it.next();
                        it.remove();
                        if (key.isValid()) {
                            if (key.isAcceptable()) {
                                this.accept(key);
                            }
                            if (key.isReadable()) {
                                this.read(key);
                            }
                            if (key.isWritable()) {
                                this.write(key);
                            }
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //发送消息
    private void write(SelectionKey key) {
        SocketChannel sc = (SocketChannel) key.channel();
        try {
            sc.configureBlocking(false);
        } catch (IOException e) {
            e.printStackTrace();
        }
  //判断是否有消息需要发送
        if(msg!=null && msg.getFlag()){
            System.out.println(msg);
            try {
                msg.setFlag(false);
                writeBuffer.clear();
                writeBuffer.put(msg.getContent().getBytes());
                writeBuffer.flip();
                sc.write(writeBuffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }

    //读取客户端消息
    private void read(SelectionKey key) {
        SocketChannel sc = (SocketChannel) key.channel();
        try {
            sc.configureBlocking(false);
            readBuffer.clear();
            int read = sc.read(readBuffer);
            if (read == -1) {
                sc.close();
                key.cancel();
            }
            readBuffer.flip();
            System.out.println(new String(readBuffer.array()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //接受客户端连接
    private void accept(SelectionKey key) {
        ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
        try {
            SocketChannel sc = ssc.accept();
            System.out.println(String.format("a new client join!!!host:%s;port:%d", sc.socket().getLocalAddress(), sc.socket().getPort()));
            sc.configureBlocking(false);
            sc.register(this.selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

Msg.java

class Msg {
    private Boolean flag=false;
    private String content;

    public Boolean getFlag() {
        return flag;
    }

    public void setFlag(Boolean flag) {
        this.flag = flag;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public String toString() {
        return "Msg{" +
                "flag=" + flag +
                ", content='" + content + '\'' +
                '}';
    }
}

MsgSender.java

class MsgSender implements Runnable{
    private Msg msg;

    public MsgSender(Msg msg) {
        this.msg = msg;
    }

    @Override
    public void run() {
        while (true) {
            System.out.println("input:\n");
            Scanner scanner = new Scanner(System.in);
            this.msg.setContent(scanner.next());
            this.msg.setFlag(true);
        }
    }
}

客户端

采用的时BIO,简单的使用线程实现消息的读写

功能:

1、连接服务端
2、读取消息
3、发送消息

public class Client {
    private SocketChannel sc;
    ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
    ByteBuffer readBuffer = ByteBuffer.allocate(1024);

    public static void main(String[] args) {
        new Client();
    }
    public Client() {
        try {
            sc = SocketChannel.open();
            //连接服务端
            sc.connect(new InetSocketAddress(8899));
            //发送消息
            this.write(sc);
            //读取消息
            this.read(sc);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void read(SocketChannel sc) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        readBuffer.clear();
                        int read = sc.read(readBuffer);
                        readBuffer.flip();
                        System.out.println(new String(readBuffer.array()));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    private void write(SocketChannel sc) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    Scanner scanner = new Scanner(System.in);
                    String next = scanner.next();
                    writeBuffer.clear();
                    writeBuffer.put(next.getBytes());
                    writeBuffer.flip();
                    try {
                        sc.write(writeBuffer);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
}

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

相关文章

  • Maven打包跳过测试的实现方法

    Maven打包跳过测试的实现方法

    使用Maven打包的时候,可能会因为单元测试打包失败,这时候就需要跳过单元测试。本文就介绍了Maven打包跳过测试的实现方法,感兴趣的可以了解一下
    2021-06-06
  • Spring @ComponentScan注解使用案例详细讲解

    Spring @ComponentScan注解使用案例详细讲解

    @ComponentScan注解的作用可以简述为:将项目中所有被@Component注解直接或者间接标记的类---->组装成BeanDefinition---->然后以key=beanName, value=BeanDefinition的形式存储,为后续生成bean对象做准备
    2023-03-03
  • springBoot项目常用目录解读

    springBoot项目常用目录解读

    这篇文章主要介绍了springBoot项目常用目录解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • 简单谈谈Java中的栈和堆

    简单谈谈Java中的栈和堆

    堆和栈都是Java用来在RAM中存放数据的地方,下面这篇文章主要给大家介绍了关于Java中栈和堆的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2021-11-11
  • ReentrantLock源码详解--公平锁、非公平锁

    ReentrantLock源码详解--公平锁、非公平锁

    ReentrantLock重入锁,是实现Lock接口的一个类,也是在实际编程中使用频率很高的一个锁,表示能够对共享资源能够重复加锁,即当前线程获取该锁再次获取不会被阻塞。下面我们来深入了解一下它吧
    2019-06-06
  • SpringBoot整合Tomcat连接池的使用

    SpringBoot整合Tomcat连接池的使用

    这篇文章主要介绍了SpringBoot整合Tomcat连接池的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Java实现简单双色球摇奖功能过程解析

    Java实现简单双色球摇奖功能过程解析

    这篇文章主要介绍了Java实现简单双色球摇奖功能过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • java实现监听u盘示例分享

    java实现监听u盘示例分享

    这篇文章主要介绍了java实现监听u盘示例,需要的朋友可以参考下
    2014-03-03
  • SpringBoot实现自定义条件注解的代码示例

    SpringBoot实现自定义条件注解的代码示例

    在Spring Boot中,条件注解是一种非常强大的工具,它可以根据特定的条件来选择是否加载某个类或某个Bean,文将介绍如何在Spring Boot中实现自定义条件注解,并提供一个示例代码,需要的朋友可以参考下
    2023-06-06
  • SSH框架网上商城项目第23战之在线支付功能实现

    SSH框架网上商城项目第23战之在线支付功能实现

    这篇文章主要为大家详细介绍了SSH框架网上商城项目第23战之在线支付功能实现,感兴趣的小伙伴们可以参考一下
    2016-06-06

最新评论