非阻塞的IO

public class NioServer {
	private static Selector selector;
	public static void main(String[] args) throws IOException {
		NioServer nioServer = new NioServer();
		nioServer.initServer(8001);
		nioServer.listen();
	}
	//获得一个通道并对该通道做一些初始化工作
	public  void initServer(int port) throws IOException {
		//创建nio通道,获取一个seversocket
		ServerSocketChannel channel = ServerSocketChannel.open();
		//设置通道为非阻塞,设置true就有异常
		channel.configureBlocking(false);
		//设置基于nio的socket
		
		ServerSocket serverSocket = channel.socket();
		//新建socket通道的端口,将该通道对应的 serverSocket绑定到port
		serverSocket.bind(new InetSocketAddress(port));
		//获取通道管理器
		selector = Selector.open();
		//将设置的通道管理器和通道绑定,并注册SelectionKey.OP_ACCEPT事件
		//当该事件到达的时候,selector.select()会返回果该事件没有到达selector.select()会阻塞
		//将nio绑定到选择器。绑定后分配的主键为selectionKey
		
		SelectionKey selectionKey = channel.register(selector, SelectionKey.OP_ACCEPT);
		
		
			
	}
	/**
	 * 采用轮询的方式监听selector。是否需要处理事件,需要就进行处理
	 * 轮询:由cpu定时发出询问,依次询问每一个周边设备是否需要服务,有就给服务,服务结束后询问下一个
	 * @throws IOException 
	 */
	public void listen() throws IOException {
		System.out.println("服务器启动成功");
		while (true) {
			//当注册的事件到达时,方法返回,否则方法一直阻塞
			//获取通道内是否有选择器的服务事件
			int  num = selector.select();
			if (num<1) {
				continue;
			}
			//获取通道服务时间的集合    ,一个是新顾客的事件,一个是老顾客
			Set selectKey = selector.selectedKeys();
			Iterator iterator = selectKey.iterator();
			while (iterator.hasNext()) {
				SelectionKey key = (SelectionKey) iterator.next();
				//删除已经处理的事件,防止重复处理
				
				iterator.remove();
				handler(key);
			}
			
		}
	}
	//处理请求是老顾客还是新顾客
	public void handler(SelectionKey key) throws IOException {
		//判断是不是新的顾客,测试此密钥的通道是否追备好接受新的套接字连接
		if (key.isAcceptable()) {
			
			handlerAccept(key);
		}else if(key.isReadable()){
			handlerRead(key);
		}
	}
	
	//处理连接事件
	public void handlerAccept(SelectionKey key) throws IOException {
		//新顾客新注册
		ServerSocketChannel channel = (ServerSocketChannel) key.channel();
		//获取客户端连接通道
		SocketChannel  socketChannel = channel.accept();
	
		//将该通道设置成非阻塞,设置成true有异常
		socketChannel.configureBlocking(false);
		//可以给客户端发信息
		System.out.println("这是新的客户端连接");
		//在和客户端连接成功后,需要给通道设置权限
		
		SelectionKey newkey = socketChannel.register(selector, SelectionKey.OP_READ);
		
		
		
	}
	//处理读的事件
	public void handlerRead(SelectionKey key) throws IOException {
		//服务器可读取客户端消息,得到时间发送的socket通道
		SocketChannel socketChannel = (SocketChannel) key.channel();
		//创建读取的缓冲区,一次能接受字节  ,相当于byte数组,存储读取数据
		ByteBuffer buffer = ByteBuffer.allocate(1024);
		//读取字节byte往buffer里面读
		int read = socketChannel.read(buffer);
		if (read>0) {
			byte[] data = buffer.array();//把buffer变成字节数组
			String mString = new String(data).trim();
			System.out.println("服务器端收到的信息"+mString);
			//回写数据,给客户端发送信息
			ByteBuffer out = ByteBuffer.wrap("好的".getBytes());
			//将信息写给客户端
			socketChannel.write(out);
			
			
			
		}else {
			System.out.println("客户端关闭");
			key.cancel();
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值