nio demo
来源:互联网 发布:redis 高并发读写优化 编辑:程序博客网 时间:2024/06/12 00:04
package com.nio.client;import java.io.IOException;import java.net.InetSocketAddress;import java.net.ServerSocket;import java.net.Socket;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.nio.charset.Charset;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Iterator;import java.util.Set;public class NIOServer { /* 缓冲区大小 */ private static final int BLOCK_SIZE = 4096; /* 接收数据缓冲区大小 */ private ByteBuffer recieveBuffer = ByteBuffer.allocate(BLOCK_SIZE); /* 发送数据缓冲区大小 */ private ByteBuffer sendBuffer = ByteBuffer.allocate(BLOCK_SIZE); /*持有一个Selector*/ private Selector selector; public NIOServer(){ } public NIOServer(int port) throws IOException{ /*SocketServerChannel:可以监听新进来的TCP连接的通道, 就像标准IO中的ServerSocket一样*/ /*创建服务器套接字通道:SocketServerChannel,内部就是实例化了一个SocketServerChannelImpl*/ ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); /* 服务器配置为非阻塞 */ serverSocketChannel.configureBlocking(Boolean.FALSE); /* 获取一个socket */ ServerSocket serverSocket = serverSocketChannel.socket(); /* 通过socket 绑定地址 */ serverSocket.bind(new InetSocketAddress("localhost",port)); /* 获取Selector:实际上window是创建了WindowsSelectorImpl实例 */ selector = Selector.open(); /* 注册到accept事件到 selector,等待连接 */ serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); System.out.println("NIO Server Start........................."); } /**一直不断的监听*/ public void listen() throws IOException { while (true){ // 监控注册在Selector上的ServerSocketChannel,返回值代表有多少channel已经就绪,可以进行I/O操作了 int ready = selector.select(); if (ready > 0) { /* * selectedKeys()返回一个SelectionKey的集合,因为完全有可能在这个Selector注册多个SelectionKey * 比如OP_ACCEPT,OP_READ,OP_WRITE等 * 其中每个SelectionKey代表了一个可以进行IO操作的channel * 一个ServerSocketChannel可以进行IO操作意味着有新的TCP连接连入了 */ Set<SelectionKey> keys = selector.selectedKeys(); SelectionKey key = null; for(Iterator<SelectionKey> it = keys.iterator();it.hasNext();){ key = (SelectionKey)it.next(); // 需要将处理过的key从selectedKeys这个集合中删除 it.remove(); handleKey(key); } } } } /**处理请求*/ public void handleKey(SelectionKey key) throws IOException{ if (key == null) { System.out.println("SelectionKey is null"); return; } ServerSocketChannel serverSocketChannel = null; SocketChannel socketChannel = null; Socket socket = null; int count = 0; /* 判断这个SelectionKey对应的channel是否已准备好接收新的TCP连接 */ if (key.isAcceptable()) { /* 从SelectionKey得到对应的channel */ serverSocketChannel = (ServerSocketChannel)key.channel(); /* 接受新的TCP连接(来自客户端) */ socketChannel = serverSocketChannel.accept(); /* 配置为非阻塞 */ socketChannel.configureBlocking(Boolean.FALSE); /* 注册到selector,等待读取 */ socketChannel.register(selector,SelectionKey.OP_READ); } else if (key.isReadable()) { //判断该通道是否已准备好读 /* 返回为之创建此键的通道 */ socketChannel = (SocketChannel)key.channel(); /* 将接收数据的缓冲区清空以备下次读取 */ recieveBuffer.clear(); /* 读取服务器发送的数据到recieveBuffer */ count = socketChannel.read(recieveBuffer); if (count >0) { String recvText = new String(recieveBuffer.array(),0,count); System.out.println("服务器端接受客户端数据--: " + recvText); socketChannel.register(selector, SelectionKey.OP_WRITE); } } else if (key.isWritable()) {//判断该通道是否已准备好写 socketChannel = (SocketChannel)key.channel(); /* 将缓冲区清空以备下次写入 */ sendBuffer.clear(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String data = dateFormat.format(new Date()); /* 向缓冲区中输入数据 */ sendBuffer.put(data.getBytes(Charset.defaultCharset())); /* 将数据输出到通道*/ socketChannel.write(sendBuffer); System.out.println("服务器端向客户端发送数据--: " + data); /* 又注册到selector,等待读取 */ socketChannel.register(selector, SelectionKey.OP_READ); } } public static void main(String[] args) throws IOException { int port = 22222; NIOServer server = new NIOServer(port); server.listen(); }}
package com.nio.client;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.nio.charset.Charset;import java.util.Iterator;import java.util.Set;public class NIOClient { /* 缓冲区大小 */ private static final int BLOCK_SIZE = 4096; /* 接收数据缓冲区大小 */ private ByteBuffer recieveBuffer = ByteBuffer.allocate(BLOCK_SIZE); /* 发送数据缓冲区大小 */ private ByteBuffer sendBuffer = ByteBuffer.allocate(BLOCK_SIZE); /* 服务器端地址 */ private final static InetSocketAddress SERVER_ADDRESS = new InetSocketAddress("localhost", 22222); public void handle() throws IOException{ /* 创建一个SocketChannel */ SocketChannel socketChannel = SocketChannel.open(); /* 设为非阻塞模式 */ socketChannel.configureBlocking(Boolean.FALSE); /* 创建Selector */ Selector selector = Selector.open(); /* 注册连接服务端socket动作 */ socketChannel.register(selector, SelectionKey.OP_CONNECT); /* 连接到服务器 */ socketChannel.connect(SERVER_ADDRESS); Set<SelectionKey> keys = null; Iterator<SelectionKey> it = null; SelectionKey key = null; int count = 0; String recvText = null; while (true) { /* 监控注册在Selector上的SocketChannel,返回值代表有多少channel已经就绪,可以进行I/O操作了*/ int ready = selector.select(); /* 其中每个SelectionKey代表了一个可以进行IO操作的channel */ keys = selector.selectedKeys(); it = keys.iterator(); while (it.hasNext()) { key = (SelectionKey)it.next(); // 判断该通道是否可以进行连接操作 if (key.isConnectable()) { System.out.println("客户端开始连接......"); /* 返回为之创建此键的通道 */ socketChannel = (SocketChannel)key.channel(); if (socketChannel.isConnectionPending()) { socketChannel.finishConnect(); System.out.println("完成连接!"); sendBuffer.clear(); sendBuffer.put("我可以连接吗".getBytes(Charset.defaultCharset())); sendBuffer.flip(); socketChannel.write(sendBuffer); } /* 又注册到selector,等待读取 */ socketChannel.register(selector, SelectionKey.OP_READ); } else if (key.isReadable()) { //判断该通道是否可以读 /* 返回为之创建此键的通道 */ socketChannel = (SocketChannel)key.channel(); //将接收数据缓冲区清空以备下次读取 recieveBuffer.clear(); //读取服务器发送来的数据到缓冲区中 count = socketChannel.read(recieveBuffer); if (count > 0) { recvText = new String(recieveBuffer.array(),0,count,Charset.defaultCharset()); System.out.println("客户端接受服务器端数据=> "+recvText); /* 又注册到selector,等待写入 */ socketChannel.register(selector, SelectionKey.OP_WRITE); } } else if (key.isWritable()) { //判断该通道是否可以写 /* 返回为之创建此键的通道 */ socketChannel = (SocketChannel)key.channel(); //将发送数据缓冲区清空以备下次读取 sendBuffer.clear(); String data = String.valueOf(Math.round(Math.random() * 100 + 1)); sendBuffer.put(data.getBytes(Charset.defaultCharset())); //将缓冲区各标志复位,因为向里面put了数据标志被改变要想从中读取数据发向服务器,就要复位 sendBuffer.flip(); socketChannel.write(sendBuffer); System.out.println("客户端向服务器端发送数据=> " + data); socketChannel.register(selector, SelectionKey.OP_READ); } } keys.clear(); } } public static void main(String[] args) throws IOException { NIOClient client = new NIOClient(); client.handle(); }}
0 0
- NIO Demo
- nio demo
- nio demo
- File NIO DEMO
- NIO Socket Server DEMO
- NIO demo:EchoServer
- Java NIO 学习demo
- NIO学习demo
- java nio demo
- NIO 实例demo-Server
- # NIO 实例demo-Client
- java Nio Demo
- java nio demo简单nio项目
- 【学习笔记】Socket NIO demo
- nio简单demo,帮助理解io与nio区别
- NIO 客户端与服务端通信demo
- Java 时间服务器demo之NIO实现
- Java NIO 同步非阻塞Socket DEMO
- 再谈原型链,深刻理解原型及原型链(案例分析,详细图解,一目了然)
- Java基础——"=="和equals方法究竟有什么区别?
- MySQL学习笔记创建表
- SSM 框架 搭建
- [Leetcode] 135. Candy 解题报告
- nio demo
- Android Studio项目与Git托管
- 血坑!!!!cronolog拆分tomcat catelina.log日志吐血总结
- HTML5开发笔记:初窥CANVAS,上传canvas图片到服务器
- 顺序队列与循环队列
- 第二章、Python如何运行程序
- 珍爱生命,远离熬夜
- Java程序员最亲睐的Web框架
- 四大组件之一ContentProvider