NIO底层代码简单Demo实例

特点:

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

开源的NIO结构的服务器框架: MINA     NETTY

NIO简单模型图:

1、实现NIO的client端

package nio.dome;

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;
import java.util.Set;

public class SocketChannelDemo {
	public static void main(String[] args) throws Exception {
		// 0.准备选择器
		Selector sele = Selector.open();
		// 1.创建sc通道对象
		SocketChannel sc = SocketChannel.open();
		// 2.设置非阻塞模式
		sc.configureBlocking(false);
		// 3.地址和端口
		sc.connect(new InetSocketAddress("127.0.0.1", 44444));
		// 4.注册事件
		sc.register(sele, SelectionKey.OP_CONNECT);
		// 选择和处理
		while (true) {
			// 执行选择的操作,惟一阻塞方法
			sele.select();
			Set<SelectionKey> keys = sele.selectedKeys();
			if (keys.size() > 0) {
				Iterator<SelectionKey> it = keys.iterator();
				while (it.hasNext()) {
					SelectionKey key = it.next();
					if (key.isAcceptable()) {

					} else if (key.isConnectable()) {
						SocketChannel channel = (SocketChannel) key.channel();
						while (!channel.isConnected()) {
							channel.finishConnect();
						}
						// 注册写事件到选择器
						channel.register(sele, SelectionKey.OP_WRITE);

					} else if (key.isWritable()) {
						// 获取write的通道
						SocketChannel channel = (SocketChannel) key.channel();
						ByteBuffer buf = ByteBuffer.wrap("hello world ".getBytes());
						while (buf.hasRemaining()) {
							channel.write(buf);
						}
						// 注册一个读操作
						channel.register(sele, SelectionKey.OP_READ);

					} else if (key.isReadable()) {
						SocketChannel channel = (SocketChannel) key.channel();
						ByteBuffer buf = java.nio.ByteBuffer.allocate(9);
						int count = -1;
						while ( channel.read(buf) != -1) {
							//channel.read(buf);
							System.out.println("sjdfs");
						}
						String str = new String(buf.array());
						System.out.println("client: " + str);

						// 取消write操作的注册,防止多次write
						key.cancel();
					} else {
						throw new Exception("ni ya! woburenshinia!");
					}
				}
				// 从就绪的键集中删除已经处理的键
				it.remove();
			}

		}
	}
}

2、实现NIO的server端

package nio.dome;

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;
import java.util.Set;

public class ServerSocketChannelDemo {
	public static void main(String[] args) throws Exception {
		// 0.创建选择器
		Selector sele = Selector.open();
		//1.创建服务器
		ServerSocketChannel ssc = ServerSocketChannel.open();
		ssc.bind(new InetSocketAddress("127.0.0.1", 44444));
		// 2.设置ssc为非阻塞
		ssc.configureBlocking(false);
		// 3.向选择器中注册ACCEPT操作
		ssc.register(sele, SelectionKey.OP_ACCEPT);
		//不停的循环选择,不停地处理
		while(true) {
			//4.选择器进行选择操作
			//该方法是NIO中唯一一个阻塞的方法,没有就绪的就阻塞
			sele.select();
			//5.获取就绪的键
			Set<SelectionKey> selectedKeys = sele.selectedKeys();
			if(selectedKeys.size() > 0) {
				Iterator<SelectionKey> it = selectedKeys.iterator();
				//6.遍历就绪的键
				while(it.hasNext()) {
					SelectionKey key = it.next();
					//7.判断当前就绪的键是什么类型的操作
					if(key.isAcceptable()) {
						ServerSocketChannel channel = (ServerSocketChannel) key.channel();
						SocketChannel sc = null;
						while(sc == null) {
							sc = channel.accept();
						}
						// 9.为读事件设置非阻塞,将sc注册到选择器中
						sc.configureBlocking(false);
						sc.register(sele, SelectionKey.OP_READ);
						
					}else if(key.isWritable()) {
						SocketChannel channel = (SocketChannel) key.channel();
						ByteBuffer buf = ByteBuffer.wrap("hello nio".getBytes());
						while(buf.hasRemaining()) {
							channel.write(buf);
						}
						//key.cancel();
						
					}else if(key.isReadable()) {
						//8.如果当前是READ操作,则去完成READ操作
						SocketChannel sc = (SocketChannel) key.channel();
						ByteBuffer buf = java.nio.ByteBuffer.allocate(11); 
						while(buf.hasRemaining()) {
							sc.read(buf);
						}
						String str = new String(buf.array());
						System.out.println("server: "+str);
						//注册写操作
						sc.register(sele, SelectionKey.OP_WRITE);
					}else {
						throw new Exception("ni ya! woburenshinia!");
					}
				}
				//10.删除处理过的就绪的键
				it.remove();
			}
		}
		
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值