`

(五)NIO-总结

    博客分类:
  • NIO
nio 
阅读更多
一、代码总结

服务端
package com.study.nio.day3;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * NIO-ServerSocketChannel 服务端
 */
public class NIOServerDemo {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {

		// 1.创建服务端channel;设置非阻塞模式,默认为true;绑定端口,接收此端口发送的信息
		ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
		serverSocketChannel.configureBlocking(false);
		serverSocketChannel.socket().bind(new InetSocketAddress(9999));
		
		// 2.创建选择器;将通道注册到选择器上;
		// 已注册集合
		Selector selector = Selector.open();
		serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
		
		// 3.服务器处于开通状态,等待客户端连接,并处理客户端的请求并响应客户端
		while(true){
			
			// 已可以接收请求的channel的数量
			// 已就绪集合
			int readyCount = selector.select();
			if(readyCount > 0){ // 可以工作
				
				Iterator iterator = selector.selectedKeys().iterator();
				while(iterator.hasNext()){
					
					SelectionKey selectionKey = (SelectionKey) iterator.next();
					if(selectionKey.isAcceptable()){
						
						ServerSocketChannel serverSocketChannelAccept = (ServerSocketChannel) selectionKey.channel();
						SocketChannel socketChannel = serverSocketChannelAccept.accept();
						socketChannel.configureBlocking(false);
						socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
						
					}else if(selectionKey.isReadable()){
						
						SocketChannel readableChannel = (SocketChannel) selectionKey.channel();
						readableChannel.configureBlocking(false);
						
						String content = NIOUtil.read(readableChannel);
						System.out.println("服务端接收"+"客户端"+readableChannel.socket().getInetAddress().getHostAddress()+"发送的信息:"+content);
					
					}else if(selectionKey.isWritable()){
						
						SocketChannel writeableChannel = (SocketChannel) selectionKey.channel();
						writeableChannel.configureBlocking(false);
						
						String content = "服务端"+writeableChannel.socket().getInetAddress().getHostAddress()+"接收到客户端的信息" ;
						NIOUtil.write(writeableChannel, content);
						
						writeableChannel.register(selector, NIOUtil.cancel(selectionKey, SelectionKey.OP_WRITE));
					}
					iterator.remove();
				}
			}
		}
	}

}



客户端
package com.study.nio.day3;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

public class NIOClientDemo {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {

		SocketChannel socketChannel = SocketChannel.open();
		socketChannel.configureBlocking(false);
		socketChannel.connect(new InetSocketAddress("127.0.0.1",9999));
		
		Selector selector = Selector.open();
		socketChannel.register(selector, SelectionKey.OP_CONNECT | SelectionKey.OP_WRITE | SelectionKey.OP_READ);
		
		while(true){
			int readyCount = selector.select();
			if(readyCount > 0){
				Iterator iterator = selector.selectedKeys().iterator();
				while(iterator.hasNext()){
					SelectionKey selectionKey = (SelectionKey) iterator.next();
					// 得到的channel即为注册的channel
					SocketChannel socketChannelKey = (SocketChannel) selectionKey.channel();
					socketChannelKey.configureBlocking(false);
					
					if(selectionKey.isConnectable()){
						// 完成连接
						socketChannel.finishConnect();
					}else if(selectionKey.isWritable()){
											
						String content = "NIO LEARNING FINISH ! NIO 学习总结" ;
						NIOUtil.write(socketChannelKey, content);
						
						socketChannel.register(selector, NIOUtil.cancel(selectionKey, SelectionKey.OP_WRITE));
					}	else if(selectionKey.isReadable()){
						
						String content = NIOUtil.read(socketChannelKey);
						System.out.println("客户端接收"+"服务端"+socketChannelKey.socket().getInetAddress().getHostAddress()+"响应的信息:"+content);
					
					}
					iterator.remove();
				}
			}
			
		}
	}

}



工具类
package com.study.nio.day3;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;

/**
 * NIO工具类
 * @description
 * 避免粘包问题,约定发送与接收数据格式为:
 * 写入:content.getBytes("utf-8").length+"\r\n"+content
 * 读取:以"\r\n"为分割,头部为数据长度,尾部为数据内容
 * 注意read 和 writer方法都无法保证是否完整的读取或写出,需要循环检查
 * while(byteBuffer.hasRemaining())
 */
public class NIOUtil {

	private static final String DEFAULT_CODED_FORMAT = "UTF-8" ;
	
	public static String read(SocketChannel socketChannel) throws IOException{
		
		int contentLength = readContentHead(socketChannel);
		return readContentTail(socketChannel, contentLength) ;
	}

	/**
	 * 读取内容的头部信息
	 * @description
	 * 处理逻辑:
	 * 建立大小为1的缓冲区
	 * 每次读入一个字符
	 * 若不是以\r\n结尾,则继续读入
	 * 				   否则结束,此时读取的结果为number\r\n 
	 * @param socketChannel
	 * @return
	 * @throws IOException
	 */
	private static int readContentHead(SocketChannel socketChannel) throws IOException{
		
		String contentHead = "" ;
		ByteBuffer temp = ByteBuffer.allocate(1);
		while(!contentHead.endsWith("\r\n")){
			socketChannel.read(temp);
			contentHead += new String(temp.array(),DEFAULT_CODED_FORMAT);
			temp.clear();
		}
		int contentLenth = Integer.valueOf(contentHead.substring(0, contentHead.length()-2)).intValue();
		return contentLenth;
	}
	
	private static String readContentTail(SocketChannel socketChannel,int contentLength) throws IOException{
		ByteBuffer byteBuffer = ByteBuffer.allocate(contentLength);
		while(byteBuffer.hasRemaining()){
			socketChannel.read(byteBuffer);
		}
		return new String(byteBuffer.array(),DEFAULT_CODED_FORMAT);
	}
	
	/**
	 * 写入数据
	 * @param socketChannel
	 * @param content
	 * @throws IOException
	 */
	public static void write(SocketChannel socketChannel ,String content) throws IOException{
		StringBuffer sb = new StringBuffer();
		sb.append(content.getBytes(DEFAULT_CODED_FORMAT).length+"").append("\r\n").append(content);
		ByteBuffer byteBuffer = ByteBuffer.wrap(sb.toString().getBytes(DEFAULT_CODED_FORMAT));
		while(byteBuffer.hasRemaining()){
			socketChannel.write(byteBuffer);
		}
	}
	
	/**
	 * 取消某op
	 * @param selecttionKey
	 * @param op
	 * @return
	 */
	public static int cancel(SelectionKey selecttionKey, int op){
		int ops = selecttionKey.interestOps();
		return ops & ~op ;
	}
}



二、IO方式
  • 阻塞/非阻塞:是从线程的角度来考虑的,考虑线程是不是被挂起的状态
  • 同步/异步:是从逻辑执行的角度来考虑的,考虑程序在处理一段逻辑时可否并行处理另一端逻辑


  • BIO -- jdk1.0 -- BlockingIO -- 同步阻塞式IO -- 面向流操作字节字符 -- 单向传输
  • NIO -- jdk1.4 -- NonBlockingIO -- 同步非阻塞式IO -- 面向通道操作缓冲区 -- 双向传输
  • AIO -- jdk1.7 -- AnsyncronizeIO -- 异步非阻塞式IO -- 大量的使用回调函数实现了异步IO操作


三种方式,各有优缺点,使用时考虑具体的应用场景。

如:上传下载文件时,若并发量大,则不可以用NIO,因为是同步处理,就会出现等待。




分享到:
评论

相关推荐

    httpcore-nio-4.4.6-API文档-中文版.zip

    赠送jar包:httpcore-nio-4.4.6.jar 赠送原API文档:httpcore-nio-4.4.6-javadoc.jar 赠送源代码:httpcore-nio-4.4.6-sources.jar 包含翻译后的API文档:httpcore-nio-4.4.6-javadoc-API文档-中文(简体)版.zip ...

    xnio-nio-3.8.0.Final-API文档-中文版.zip

    赠送jar包:xnio-nio-3.8.0.Final.jar; 赠送原API文档:xnio-nio-3.8.0.Final-javadoc.jar; 赠送源代码:xnio-nio-3.8.0.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.0.Final.pom; 包含翻译后的API...

    httpcore-nio-4.4.15-API文档-中文版.zip

    赠送jar包:httpcore-nio-4.4.15.jar 赠送原API文档:httpcore-nio-4.4.15-javadoc.jar 赠送源代码:httpcore-nio-4.4.15-sources.jar 包含翻译后的API文档:httpcore-nio-4.4.15-javadoc-API文档-中文(简体)版....

    httpcore-nio-4.4.10-API文档-中文版.zip

    赠送jar包:httpcore-nio-4.4.10.jar; 赠送原API文档:httpcore-nio-4.4.10-javadoc.jar; 赠送源代码:httpcore-nio-4.4.10-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.10.pom; 包含翻译后的API文档...

    httpcore-nio-4.4.10-API文档-中英对照版.zip

    赠送jar包:httpcore-nio-4.4.10.jar; 赠送原API文档:httpcore-nio-4.4.10-javadoc.jar; 赠送源代码:httpcore-nio-4.4.10-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.10.pom; 包含翻译后的API文档...

    httpcore-nio-4.4.15-API文档-中英对照版.zip

    赠送jar包:httpcore-nio-4.4.15.jar 赠送原API文档:httpcore-nio-4.4.15-javadoc.jar 赠送源代码:httpcore-nio-4.4.15-sources.jar 包含翻译后的API文档:httpcore-nio-4.4.15-javadoc-API文档-中文(简体)-...

    xnio-nio-3.8.4.Final-API文档-中英对照版.zip

    赠送jar包:xnio-nio-3.8.4.Final.jar; 赠送原API文档:xnio-nio-3.8.4.Final-javadoc.jar; 赠送源代码:xnio-nio-3.8.4.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.4.Final.pom; 包含翻译后的API...

    xnio-nio-3.8.0.Final-API文档-中英对照版.zip

    赠送jar包:xnio-nio-3.8.0.Final.jar; 赠送原API文档:xnio-nio-3.8.0.Final-javadoc.jar; 赠送源代码:xnio-nio-3.8.0.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.0.Final.pom; 包含翻译后的API...

    httpcore-nio-4.4.5-API文档-中文版.zip

    赠送jar包:httpcore-nio-4.4.5.jar; 赠送原API文档:httpcore-nio-4.4.5-javadoc.jar; 赠送源代码:httpcore-nio-4.4.5-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.5.pom; 包含翻译后的API文档:...

    httpcore-nio-4.4.14-API文档-中文版.zip

    赠送jar包:httpcore-nio-4.4.14.jar; 赠送原API文档:httpcore-nio-4.4.14-javadoc.jar; 赠送源代码:httpcore-nio-4.4.14-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.14.pom; 包含翻译后的API文档...

    httpcore-nio-4.4.6-API文档-中英对照版.zip

    赠送jar包:httpcore-nio-4.4.6.jar; 赠送原API文档:httpcore-nio-4.4.6-javadoc.jar; 赠送源代码:httpcore-nio-4.4.6-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.6.pom; 包含翻译后的API文档:...

    nio-multipart-parser-1.1.0.jar

    java运行依赖jar包

    httpcore-nio-4.4.12-API文档-中文版.zip

    赠送jar包:httpcore-nio-4.4.12.jar; 赠送原API文档:httpcore-nio-4.4.12-javadoc.jar; 赠送源代码:httpcore-nio-4.4.12-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.12.pom; 包含翻译后的API文档...

    xnio-nio-3.8.4.Final-API文档-中文版.zip

    赠送jar包:xnio-nio-3.8.4.Final.jar; 赠送原API文档:xnio-nio-3.8.4.Final-javadoc.jar; 赠送源代码:xnio-nio-3.8.4.Final-sources.jar; 赠送Maven依赖信息文件:xnio-nio-3.8.4.Final.pom; 包含翻译后的API...

    httpcore-nio-4.3.jar包

    用Java实现非阻塞通信 ,用ServerSocket和Socket来编写服务器程序和客户程序,是Java网络编程的最基本的方式。 httpcore-nio-4.3.jar包

    httpcore-nio-4.4.4-API文档-中文版.zip

    赠送jar包:httpcore-nio-4.4.4.jar; 赠送原API文档:httpcore-nio-4.4.4-javadoc.jar; 赠送源代码:httpcore-nio-4.4.4-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.4.pom; 包含翻译后的API文档:...

    httpcore-nio-4.4.12-API文档-中英对照版.zip

    赠送jar包:httpcore-nio-4.4.12.jar; 赠送原API文档:httpcore-nio-4.4.12-javadoc.jar; 赠送源代码:httpcore-nio-4.4.12-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.12.pom; 包含翻译后的API文档...

    httpcore-nio-4.4.4-API文档-中英对照版.zip

    赠送jar包:httpcore-nio-4.4.4.jar; 赠送原API文档:httpcore-nio-4.4.4-javadoc.jar; 赠送源代码:httpcore-nio-4.4.4-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.4.pom; 包含翻译后的API文档:...

    httpcore-nio-4.4.5-API文档-中英对照版.zip

    赠送jar包:httpcore-nio-4.4.5.jar; 赠送原API文档:httpcore-nio-4.4.5-javadoc.jar; 赠送源代码:httpcore-nio-4.4.5-sources.jar; 赠送Maven依赖信息文件:httpcore-nio-4.4.5.pom; 包含翻译后的API文档:...

    httpcore-nio-4.0.1.jar

    httpcore-nio-4.0.1.jar

Global site tag (gtag.js) - Google Analytics