一步一步理解Java NIO(下)
来源:互联网 发布:mysql分页limit0,1 编辑:程序博客网 时间:2024/06/05 14:22
阻塞与非阻塞IO
选择器Selector
首先来看阻塞式网络IO通信:
package NIOTest;import org.junit.Test;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.nio.file.Paths;import java.nio.file.StandardOpenOption;/** * Created by yangl on 2017/7/7. * NIO完成网络通信的三个核心 * 1.通道(Channel):负责连接 * java.nio.channels.Channel * |--SelcectableChannel * |--SocketChannel * |--ServerSocketChannel * |--DatagramChannel * * |--Pipe.SinkChannel * |--Pipe.SourceChannel * 2.缓冲区(Buffer):负责数据的存取 * * 3.选择器(Selector):是SelectableChannel的多路复用器,用于监控SelectableChannel的IO状况 */public class NIO_Blocking2 { @Test public void client() throws IOException { //获取通道 SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",9898)); FileChannel inChannel = FileChannel.open(Paths.get("C:\\MyCode\\Java\\JavaTest\\src\\NIOTest\\1.jpg"), StandardOpenOption.READ); //分配指定大小的额缓冲区 ByteBuffer buf = ByteBuffer.allocate(1024); //读取本地文件,并发送到服务端 while(inChannel.read(buf) != -1) { buf.flip(); socketChannel.write(buf); buf.clear(); } socketChannel.shutdownOutput(); //接受服务端的反馈 int len = 0; while (socketChannel.read(buf) != -1) { buf.flip(); System.out.println(new String(buf.array(),0,len)); buf.clear(); } inChannel.close(); socketChannel.close(); } @Test public void server() throws IOException { //获取通道 ServerSocketChannel ssChannel = ServerSocketChannel.open(); FileChannel outChannel = FileChannel.open(Paths.get("C:\\MyCode\\Java\\JavaTest\\src\\NIOTest\\2.jpg"),StandardOpenOption.WRITE,StandardOpenOption.CREATE); //绑定连接 ssChannel.bind(new InetSocketAddress(9898)); //获取客户端连接的通道 SocketChannel sChannel = ssChannel.accept(); //分配指定大小的缓冲区 ByteBuffer buf = ByteBuffer.allocate(1024); //获取客户端的数据,并保存到本地 while(sChannel.read(buf) != -1) { buf.flip(); outChannel.write(buf); buf.clear(); } //发送反馈给客户端 buf.put("服务端接收数据成功".getBytes()); buf.flip(); sChannel.write(buf); sChannel.close(); ssChannel.close(); outChannel.close(); }}
Selector的应用
package NIOTest;import org.junit.Test;import sun.nio.ch.SelChImpl;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.*;import java.nio.file.Paths;import java.nio.file.StandardOpenOption;import java.util.Date;import java.util.Iterator;import java.util.Scanner;/** * Created by yangl on 2017/7/7. * NIO完成网络通信的三个核心 * 1.通道(Channel):负责连接 * java.nio.channels.Channel * |--SelcectableChannel * |--SocketChannel * |--ServerSocketChannel * |--DatagramChannel * * |--Pipe.SinkChannel * |--Pipe.SourceChannel * 2.缓冲区(Buffer):负责数据的存取 * * 3.选择器(Selector):是SelectableChannel的多路复用器,用于监控SelectableChannel的IO状况 */public class NIO_NonBlocking { @Test public void client() throws IOException { //获取通道 SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",9898)); //切换成非阻塞模式 socketChannel.configureBlocking(false); //分配指定大小的额缓冲区 ByteBuffer buf = ByteBuffer.allocate(1024); //4. 发送数据给服务端 Scanner scan = new Scanner(System.in); while(scan.hasNext()){ String str = scan.next(); buf.put((new Date().toString() + "\n" + str).getBytes()); buf.flip(); socketChannel.write(buf); buf.clear(); } socketChannel.close(); } @Test public void server() throws IOException { System.out.println("Server ......"); //获取通道 ServerSocketChannel ssChannel = ServerSocketChannel.open(); //切换成非阻塞模式 ssChannel.configureBlocking(false); //绑定连接 ssChannel.bind(new InetSocketAddress(9898)); //获取选择器 Selector selector = Selector.open(); //将通道注册到选择器,并且指定监听事件 ssChannel.register(selector,SelectionKey.OP_ACCEPT); //轮训地获取选择器上准备就绪的事件 while (selector.select() > 0) { //获取当前选择器中所有注册的“选择键”(已经就绪的监听事件) Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()){ //获取准备就绪的事件 SelectionKey sk = it.next(); //判断就绪事件的类型 if (sk.isAcceptable()){ SocketChannel socketChannel = ssChannel.accept(); //切换非阻塞模式 socketChannel.configureBlocking(false); //将通道注册到选择器上 socketChannel.register(selector,SelectionKey.OP_READ); } else if (sk.isReadable()){ SocketChannel socketChannel2 = (SocketChannel)sk.channel(); //读取数据 ByteBuffer buf = ByteBuffer.allocate(1024); int len = 0; while ((len = socketChannel2.read(buf)) > 0){ buf.flip(); System.out.println(new String(buf.array(),0,len)); buf.clear(); } it.remove(); } } } }}
阅读全文
1 0
- 一步一步理解Java NIO(下)
- 一步一步理解Java NIO(上)
- 深入理解java NIO
- 理解Java NIO
- 理解Java NIO
- 理解Java NIO
- 理解Java NIO
- 理解Java NIO
- 理解Java NIO
- Java NIO 理解
- 深入理解Java NIO
- java NIO理解
- Java NIO(一) 初步理解NIO
- Java NIO(下)
- JAVA NIO技术(下)
- JAVA NIO之个人理解
- JAVA NIO原理个人理解
- java BIO,NIO,AIO 理解
- 前端页面小技能
- PAT(乙级)1018
- C++之操作符重载学习笔记
- 使用事件和消息队列实现分布式事务
- 字符串排列组合
- 一步一步理解Java NIO(下)
- 浅谈Web网站架构演变过程[转载]
- 当自动化安装遇到ncurse界面的解决方法(取消交互的通用方法)
- SpringBoot系列(4)---SpringMVC测试用例
- 解决Lightmap在PC上与ios和Android上表现不…
- mysql分页大数据性能优化
- Q_OBJECT宏
- kernel日志时间转换函数
- collection集合学习笔记