nio底层如果通过selector进行c/s通信

传统的BIO - Blocking IO - 阻塞式IO
BIO的缺点

  1. 如果有大量的请求访问服务器,那么就要产生大量的线程去应对这些请求,导致服务器资源过于紧张
  2. 在完成一次任务的过程中需要创建大量的输入或者输出流。
  3. 数据通过流传输,无法实现定点操作
  4. 阻塞模式
    NIO - New IO - 非阻塞式IO:Buffer,Channel,Selector — Buffer是容器,用于存储数据;Channel用于传输;Selector进行过滤。
    Buffer - 缓冲区
    用于进行数据的存储。操作的都是基本类型。
    数据在操作的时候是根据操作位的位置决定。
    限制位是决定操作位所能达到的最大下标
    标记位<= 操作位<= 限制位<= 容量位
    Channel - 通道
    传输数据,基于缓冲区进行传输。可以进行双向传输。
    Selector - 多路复用通道选择器
    底层如果通过selector进行c/s通信的代码实现

ClientSelector类

public static void main(String[] args) throws IOException {
		
		SocketChannel sc=SocketChannel.open();
		
		sc.configureBlocking(false);
		
		sc.connect(new InetSocketAddress("localhost", 8090));
		
		Selector selc=Selector.open();
		
		sc.register(selc, SelectionKey.OP_CONNECT);
		
		while(true){
			selc.select();
			Set <SelectionKey> keys=selc.selectedKeys();
			Iterator<SelectionKey> it=keys.iterator();
			
			while(it.hasNext()){
				SelectionKey key=it.next();
				
				if(key.isConnectable()){
					
					SocketChannel scx=(SocketChannel) key.channel();
					
					while(!scx.finishConnect());
					
					scx.register(selc, SelectionKey.OP_READ|SelectionKey.OP_WRITE);
				}
				
				if(key.isReadable()){
					
					SocketChannel scx=(SocketChannel) key.channel();
					
					ByteBuffer buffer=ByteBuffer.allocate(1024);
					scx.read(buffer);
					System.out.println(new String(buffer.array(),0,buffer.position()));
					sc.register(selc, key.interestOps()^SelectionKey.OP_READ);
					
				}
				
				if(key.isWritable()){
					
					SocketChannel scx=(SocketChannel) key.channel();
					
					scx.write(ByteBuffer.wrap("你好服务器".getBytes()));
					
					sc.register(selc,key.interestOps()^SelectionKey.OP_WRITE);
				}
				it.remove();
				
				
			}
			
			
		}
		
	}
	

ServerSelector类

public static void main(String[] args) throws IOException {
		ServerSocketChannel ssc=ServerSocketChannel.open();
		
		ssc.bind(new InetSocketAddress(8090));
		
		ssc.configureBlocking(false);
		Selector selc=Selector.open();
		
		ssc.register(selc, SelectionKey.OP_ACCEPT);
		while(true){
			selc.select();
			Set <SelectionKey> keys=selc.selectedKeys();
			Iterator<SelectionKey> it=keys.iterator();
			while (it.hasNext()) {
				SelectionKey key =  it.next();
				if(key.isAcceptable()){
					ServerSocketChannel sscx=(ServerSocketChannel) key.channel();
					SocketChannel sc=sscx.accept();
					while(sc==null)
						sc=sscx.accept();
					
					sc.configureBlocking(false);
					
					sc.register(selc, SelectionKey.OP_READ| SelectionKey.OP_WRITE);
				}
				if(key.isReadable()){
					
					SocketChannel sc=(SocketChannel) key.channel();
					
					ByteBuffer buffer=ByteBuffer.allocate(1024);
					sc.read(buffer);
					System.out.println(new String(buffer.array(),0,buffer.position()));
					sc.register(selc,key.interestOps()^SelectionKey.OP_READ);
				}
				
				if(key.isWritable()){
					
					SocketChannel sc=(SocketChannel) key.channel();
					
					sc.write(ByteBuffer.wrap("你好客户端".getBytes()));
					
					sc.register(selc, key.interestOps()^SelectionKey.OP_WRITE);
				}
				it.remove();
			}
		}
	}

猜你喜欢

转载自blog.csdn.net/qq_43045898/article/details/83143356