netty(一)

package com.fuchanghai.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.Iterator;

public class MyNIOClient {
	private Selector selector=null;
public void initClient (String ip , int port) throws IOException{
	//相当于bio中的serversocket
	ServerSocketChannel serverChannel= ServerSocketChannel.open();
	//设置非阻塞
	serverChannel.configureBlocking(false);
	//绑定到对应的端口
	serverChannel.socket().bind(new InetSocketAddress(ip, port));
	this.selector=Selector.open();
	//将通道选择器和通道绑定,一有时间连接就注册成accept
	serverChannel.register(selector,SelectionKey.OP_ACCEPT);
}
public void listen(){
	//轮询事件管理器(多路复用器)
	while(true){
		try {
			//阻塞处,可设置时间使其不阻塞
			this.selector.select();
                        //此处设置时间
			//获取所有的注册的事件
			Iterator<?> iteratorKey =this.selector.selectedKeys().iterator();
			//取出注册的事件,并交给handle方法处理
			while (iteratorKey.hasNext()){
				SelectionKey selectionKey=(SelectionKey) iteratorKey.next();
				iteratorKey.remove();
				handle(selectionKey);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	 
}
public void handle(SelectionKey selectionKey) throws IOException{
	
	if(selectionKey.isAcceptable()){
		//如果是新接入进来的  那么将ServerSockteChannel 得到,并且将其注册到selector中
		ServerSocketChannel  serverSocketChannel =(ServerSocketChannel) selectionKey.channel();
		SocketChannel socketChannel =serverSocketChannel.accept();
		socketChannel.configureBlocking(false);
		//给通道设置读的权限。这样服务器才能经过通道读到客户端发来的信息
		socketChannel.register(selector,SelectionKey.OP_READ);
	}else if (selectionKey.isReadable()) {
		SocketChannel socketChannel =(SocketChannel) selectionKey.channel();
		ByteBuffer bf = ByteBuffer.allocate(1024);
		int data=socketChannel.read(bf);
		if(data!=-1){
			String msg =new String(bf.array(),"GBK");
		}
	}
	
}
}

下面是我在听课期间模拟老师讲的实例化的流程图


首先client1到4 就是客户端发起的链接, 虚线部分实际上在代码中没有实现。实线为实现了的。 传统bio 一个client对应的服务端就需要创建一个线程。如诺无线创建线程,那么机器碰到大量的请求总会爆掉。如诺设置个线程池限制线程数量防止线程过多。实际上高并发的时候是不够用的。

使用了nio我们会将各种读写时间,和链接事件都交给selector管理。绑定类型(例如SelectionKey.OP_ACCEPT,注accpet是请求接收类型,connect是已接收类型)使得listen()知道client 要进行哪种操作。这4个顾客发起任何类型请求都会注册到selector中listen()中 ,死循环取得多路复用器中的事件(selector.select())就相当于一个服务员给多个顾客服务,即取得顾客放入selector中的请求。 我们在上面的代码中设置时间(有个注解叫设置时间的),使得程序非阻塞。实际上如果顾客1的点餐请求花费时间太长的话,还是会阻塞其他顾客的请求的。这只是初步了解。之后还要更新

转载于:https://my.oschina.net/u/4042146/blog/2980118

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值