Java NIO初试
Java的NIO采用selector来轮循,还是不错,小试牛刀,下附代码
Server:
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.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;public class NIOServer {private Selector selector;public void initServer(int port) throws IOException {ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();// 打开服务器套接字通道serverSocketChannel.configureBlocking(false);// 设置为非阻塞模式serverSocketChannel.socket().bind(new InetSocketAddress(port));// 绑定端口this.selector = Selector.open();// 打开选择器// 注册事件,当事件到达,selector。select()会返回,如果没有事件会一直阻塞serverSocketChannel.register(this.selector, SelectionKey.OP_ACCEPT);// 注册选择器,接受客户端连接}public void listen() throws IOException {System.out.println("服务器启动!开始轮询监听消息");while (true) {int ready = this.selector.select();if (ready == 0) {continue;}Iterator items = this.selector.selectedKeys().iterator();while (items.hasNext()) {SelectionKey key = (SelectionKey) items.next();// 删除已经选择的key,防止重复处理items.remove();// 请求连接if (key.isAcceptable()) {ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();if (serverSocketChannel == null) {continue;}SocketChannel socketChannel = serverSocketChannel.accept();//每次接受新的连接请求会产生新的通道,socketChannel.configureBlocking(false);socketChannel.write(ByteBuffer.wrap(new String("你好,客户端,连接已建立,可以开始通信!").getBytes()));//连接成功,发消息给客户端System.out.println("连接已经建立");socketChannel.register(this.selector, SelectionKey.OP_READ);//准备好接收数据} else if (key.isReadable()) {this.read(key);}}}}public void read(SelectionKey key) throws IOException {SocketChannel socketChannel = (SocketChannel) key.channel();ByteBuffer byteBuffer = ByteBuffer.allocate(100);socketChannel.read(byteBuffer);byte[] data = byteBuffer.array();String msg = new String(data).trim();if (msg.equals("close~!@#$%")) {//收到关闭指令,发送确认关闭的指令给客户端,结束自身通道ByteBuffer sendBuffer = ByteBuffer.wrap(new String("bye close").getBytes());while (sendBuffer.hasRemaining()) {socketChannel.write(sendBuffer);}socketChannel.close();System.out.println("已经关闭");} else {System.out.println("server Receive:" + msg);//服务器收到任何消息都会给客户端发送"收到"socketChannel.write(ByteBuffer.wrap(new String("收到!").getBytes()));}}public static void main(String[] args) {NIOServer server = new NIOServer();try {server.initServer(1377);server.listen();} catch (IOException e) {e.printStackTrace();}}
}
Client:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
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;public class NIOClient {private Selector selector;//初始化public void initClient(String ipAddress, int port) throws IOException {SocketChannel socketChannel = SocketChannel.open();//打开套接字通道socketChannel.configureBlocking(false);//非阻塞this.selector = Selector.open();//打开选择器socketChannel.connect(new InetSocketAddress(ipAddress, port));//指定ip地址和端口号用于连接socketChannel.register(this.selector, SelectionKey.OP_CONNECT);//通道注册到选择器中,用于连接}//监听public void listen() throws IOException {while (true) {//当客户端关闭的时候需要结束轮循的动作,这样程序才会结束if (!this.selector.isOpen()) {return;}int ready = this.selector.select();//这个才是真正的轮循啦,得到通道if (ready == 0) {continue;//如果selector中没有SocketChannel,直接开始下一次咯 }Iterator items = this.selector.selectedKeys().iterator();while (items.hasNext()) {SelectionKey key = (SelectionKey) items.next();items.remove();//防止重复处理if (key.isConnectable()) {//连接System.out.println("正在连接,连接成功后,服务器会返回结果!");SocketChannel socketChannel = (SocketChannel) key.channel();// 如果正在连接,则完成连接if (socketChannel.isConnectionPending()) {socketChannel.finishConnect();}socketChannel.register(this.selector, SelectionKey.OP_READ);//重新注册该通道,用于读取数据} else if (key.isReadable()) {//读取this.read(key);}}}}/****************************************************//** 客户端关闭思路* 客户端 服务器* * 用户输入bye,需要关闭客户端* * "close~!@#$%" -> "close~!@#$%" 约定好的内容("close~!@#$%")* * "bye close" <- "bye close" ----->服务器通道关闭 约定好的内容("bye close")* * 客户端通道关闭 服务器还可以接受别的请求* */public void read(SelectionKey key) throws IOException {SocketChannel socketChannel = (SocketChannel) key.channel();ByteBuffer receiveBuffer = ByteBuffer.allocate(100);socketChannel.read(receiveBuffer);byte[] data = receiveBuffer.array();String msg = new String(data).trim();if (msg.equals("bye close")) {//客户端和服务器约定关闭,收到服务器响应后可以关闭System.out.println("关闭");socketChannel.close();this.selector.close();return;}System.out.println("client receive:" + msg);BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));String readMsg = reader.readLine();ByteBuffer sendBuffer = ByteBuffer.allocate(256);sendBuffer.clear();if(readMsg.equals("bye")){//告诉服务器,准备要撤退,当服务器返回bye close,关闭通道和选择器System.out.println("准备关闭");sendBuffer.put("close~!@#$%".getBytes());sendBuffer.flip();}else{sendBuffer.put(readMsg.getBytes());sendBuffer.flip();}while (sendBuffer.hasRemaining()) {socketChannel.write(sendBuffer);}}public static void main(String[] args) {NIOClient client = new NIOClient();try {client.initClient("127.0.0.1", 1377);client.listen();} catch (IOException e) {e.printStackTrace();}}
}
客户端可开启多个,用于连接服务器端,亲测可用,有问题联系作者,xusong1313@qq.com
业务逻辑可自己完善,其实建议的搭建不难
转载于:https://www.cnblogs.com/weiki/p/4465958.html
Java NIO初试相关推荐
- java NIO详解
http://zalezone.cn/2014/09/17/NIO%E7%B2%BE%E7%B2%B9/ 1. 前言 我们在写java程序的时候,为了进行优化,把全部的精力用在了处理效率上,但是对IO ...
- java nio设计模式_Java NIO:浅析I/O模型
也许很多朋友在学习NIO的时候都会感觉有点吃力,对里面的很多概念都感觉不是那么明朗.在进入Java NIO编程之前,我们今天先来讨论一些比较基础的知识:I/O模型.下面本文先从同步和异步的概念 说起, ...
- java语言的实现机制_JAVA语言之Java NIO的工作机制和实现原理介绍
本文主要向大家介绍了JAVA语言之Java NIO的工作机制和实现原理介绍,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助. 前言 本文只简单介绍NIO的原理实现和基本工作流程 I/O和 ...
- java大文件读写操作,java nio 之MappedByteBuffer,高效文件/内存映射
http://langgufu.iteye.com/blog/2107023 java处理大文件,一般用BufferedReader,BufferedInputStream这类带缓冲的Io类,不过如果 ...
- Java NIO系列教程(二) Channel
为什么80%的码农都做不了架构师?>>> Java NIO的通道类似流,但又有些不同: 既可以从通道中读取数据,又可以写数据到通道.但流的读写通常是单向的. 通道可以异步地读写 ...
- 11 Java NIO Non-blocking Server-翻译
尽管你对Java NIO的工作原理很了解,但是设计一个非阻塞的服务器仍然困难.与阻塞的IO相比,非阻塞的IO也包含一些挑战.这里将会讨论一些非阻塞服务器所面临的一些挑战,以及一些可行的方案. 查找关于 ...
- Java NIO系列教程(六) Selector
Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件.这样,一个单独的线程可以管理多个channel,从而管理多个网络连接. 下面是 ...
- Java NIO使用及原理分析(三)
2019独角兽企业重金招聘Python工程师标准>>> 转载自:李会军•宁静致远 在上一篇文章中介绍了缓冲区内部对于状态变化的跟踪机制,而对于NIO中缓冲区来说,还有很多的内容值的学 ...
- java nio 写事件_Java NIO
java Nio Selector 选择器 Buffer 缓冲器 Channel 通道 Selector是NIO的核心,是channel的管理者,通过执行select()阻塞方式,监听是否有chann ...
- 万字长文:助你攻破 JAVA NIO 技术壁垒
本文来源:https://honeypps.com/java/java-nio-quick-start/ 现在使用NIO的场景越来越多,很多网上的技术框架或多或少的使用NIO技术,譬如Tomcat,J ...
最新文章
- 关闭Windows 2000/XP/2003默认共享
- LA3027简单带权并查集
- 【Android 逆向】Linux 文件权限 ( Linux 权限简介 | 系统权限 | 用户权限 | 匿名用户权限 | 读 | 写 | 执行 | 更改组 | 更改用户 | 粘滞 )
- hadoop hive安装手记(转)
- mysql dba系统学习(7)二进制日志binlog之三
- 重温c语言之环境变量
- Java设计模式之策略模式---写的比较有趣,推荐大家看看
- Jerry Wang 2014年1月3日top liked SCN博客
- javascript --- 几个其他的跨域技术(图像Ping、JSONP、Comet)
- 移植opencv3.20到3556AV100
- 20155222 2016-2017-2 《Java程序设计》第8周学习总结
- VC++的学习(基于VS2008)——windows程序内部运行机制
- 2019 年编写现代 JavaScript 代码的5个小技巧
- Affinity Publisher for Mac排版设计工具
- 管理感悟:一种人才分类
- 硬件知识:打印机常见的故障及维护,值得收藏!
- HTML5的文档声明
- 快恢复二极管工作原理及使用
- 永磁同步电机的矢量控制策略(八)一一一仿真模型搭建与源代码
- 用python画年度和月度的日历图