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(); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
Spring @ComponentScan注解使用案例详细讲解
@ComponentScan注解的作用可以简述为:将项目中所有被@Component注解直接或者间接标记的类---->组装成BeanDefinition---->然后以key=beanName, value=BeanDefinition的形式存储,为后续生成bean对象做准备2023-03-03
最新评论