JavaNIO非阻塞模式

Posted fliay

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaNIO非阻塞模式相关的知识,希望对你有一定的参考价值。

package com.java.NIO;

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.Date;
import java.util.Iterator;
import java.util.Scanner;

import org.junit.Test;

/**
 * 
 * @author fliay
 *
 *	一、使用NIO 完成网络通信的三个核心
 *	1.通道(channel):负责链接
 *		java.nio.channels.Channel 接口
 *			|--SelecttableChannel
 *				|--SocketChannel
 *				|--serverSocketChannel
 *				|--DatagramChannel
 *				
 *				|--Pipe.SinkChannel
 *				|--Pipe.SourceChannel
 *	2.缓冲区(Buffer):负责数据的存取
 *
 *	3.寻则其(Selector): 是SelectableChannel的多路复用器,用于监控SelectableChannel的IO状况
 *
 *
 */
public class TestNoBlockingNIO {
	
	
	@Test//客户端
	public void client() throws IOException{
		//1.获取通道
		SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 1008));
		
		//2.切换非阻塞模式
		sChannel.configureBlocking(false);
		
		//3.分配指定大小的缓冲区
		ByteBuffer buf = ByteBuffer.allocate(1024);
		
		//4.发送数据给服务器
		Scanner input = new Scanner(System.in);
		
		
		while(input.hasNext()){
			String str = input.nextLine();
			buf.put((new Date().toString()+":\n"+str).getBytes());
			buf.flip();
			sChannel.write(buf);
			buf.clear();
		}
		
		//5.关闭通道
		sChannel.close();
		
	}
	
	@Test //服务器
	public void Server() throws IOException{
		//1.获取通道
		ServerSocketChannel ssChannel = ServerSocketChannel.open();
		
		//2.切换非阻塞模式
		ssChannel.configureBlocking(false);
		
		//3.绑定连接
		ssChannel.bind(new InetSocketAddress(1008));
		
		//4.获取选择器
		Selector selector = Selector.open();
		
		//5.将通道注册到选择器上,并且指定“监听接收事件”
		ssChannel.register(selector, SelectionKey.OP_ACCEPT);
		
		//6.轮训式的获获取选择器上的以及“准备就绪”的事件
		while(selector.select()>0){
			//7.获取当前选择器中所有注册的“选择键(已就绪的监听事件)”
			Iterator<SelectionKey> it = selector.selectedKeys().iterator();
			while(it.hasNext()){
				//8.获取就绪的事件
				SelectionKey sk = it.next();
				//9.判断具体是什么事件准备就绪
				if(sk.isAcceptable()){
					//10. 若“接受就绪” ,获取客户链接
					SocketChannel sChannel = ssChannel.accept();
					//11. 切换非阻塞模式
					sChannel.configureBlocking(false);
					//12. 将该通道注册到选择器上
					sChannel.register(selector, SelectionKey.OP_READ);
				}else if(sk.isReadable()){
					//13. 获取当前选择器上“读就绪”状态的通道
					SocketChannel sChannel = (SocketChannel) sk.channel();
					
					//14. 读取数据
					ByteBuffer buf= ByteBuffer.allocate(1024);
					
					int len =0;
					while((len =sChannel.read(buf))>0){
						buf.flip();
						System.out.println(new String(buf.array(),0,len));
						buf.clear();
					}
					
					
				}
				//15. 取消选择键 SelectionKey
				it.remove();
			}
			
		}
	}
	
	
}

  

以上是关于JavaNIO非阻塞模式的主要内容,如果未能解决你的问题,请参考以下文章

使用带有选择器的非阻塞模式下的 Java NIO 和 Unix 域套接字

Java NIO 非阻塞模式 vs node.js 异步操作

Java NIO 非阻塞模式 vs node.js 异步操作

Java NIO 在阻塞模式下相对于传统 I/O 的优势?

同步/异步/阻塞/非阻塞

JAVA NIO(死磕1)