BIO NIO学习笔记

BIO: blocking io
一个线程处理一个客户端连接和读写事件
缺点:效率低,浪费线程资源,一个线程只能处理一个连接
伪代码:

ServerSocket serverSocket = new ServerSocket(8090);
while (true){
	Socket clientSocket = serverSocket.accept(); //阻塞,等待客户端连接
	Byte[] bytes = new Byte[1024];
	int n = clientSocket.getInputStream.read(bytes); //阻塞,等待客户端发送数据
	if (n != -1){
		System.out.println("收到客户端数据:"+ new String(bytes));
		clientSocket.getOutputStream.write("hello client".getBytes());
		clientSocket.getOutputStream.flush();
	}
}

NIO: nonBlocking io
一个线程处理多个客户端连接和读写事件
简单版本的缺点:会遍历所有连接,每个连接都去读一次数据,如果所有连接中只有少部分发送数据,则大部分遍历是无效的
简单版本伪代码:

List<SocketChannel> channelList = new LinkedList<>();
ServerSocketChannel serverSocket = ServerSocketChannel.open();
serverSocket.socket().bind(new InetSocketAddress(8090));
serverSocket.configureBlocking(false); //设置为非阻塞
while (true){
	SocketChannel socketChannel = serverSocket.accept(); //不会阻塞,不管有没有客户端连接都会往下执行
	while (socketChannel != null){
		socketChannel.configureBlocking(false);
		channelList.add(socketChannel);
	}
	Iterator<SocketChannel> iterator = channelList.iterator();
	while (iterator.hasNext()){
		SocketChannel sc = iterator.next();
		ByteBuffer buffer = ByteBuffer.allocate(256);
		int n = sc.read(buffer);//不会阻塞,不管客户端又没有发送数据都会往下执行
		if (n > 0){
			System.out.println(new String(buffer.array()));
		} else if(n == -1){//客户端端口,从集合中移出
			iterator.remove();
			sc.close();
		}
	}
}

引入多路复用器的版本:


ServerSocketChannel serverSocket = ServerSocketChannel.open();
serverSocket.socket().bind(new InetSocketAddress(8090));
serverSocket.configureBlocking(false); //设置为非阻塞
Selector selector = Selector.open();
serverSocket.register(selector,SelectionKey.OP_ACCEPT);
while (true){
	selector.select();
	Set<SelectionKey> selectionKeys = selector.selectionKeys();
	Iterator<SelectionKey> iterator selectionKeys.iterator();
	while (iterator.hasNext()){
		SelectionKey selectionKey = iterator.next();
		if (selectionKey.isAcceptable){//连接事件
			ServerSocketChannel serverSocketChannel = (ServerSocketChannel)selectionKey.channel();
			SocketChannel socketChannel = serverSocketChannel.accpet();
			socketChannel.configureBlocking(false);//设置为非阻塞
			socketChannel.register(selector, SelectionKey.OP_READ);
		} else if (selectionKey.isReadable){
			SocketChannel socketChannel = selectionKey.channel();
			ByteBuffer buffer = ByteBuffer.allocate();
			int n = socketChannel.read(buffer);
			if (n >0){
				System.out.println(new String(buffer));
			} else if (n == -1){
				socketChannel.close();
			}
		}
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值