`

java 高性能网络编程 NIO

    博客分类:
  • java
 
阅读更多

 服务器端:

 

 

 // 1. 分配一个 ServerSocketChannel 文件描述符
            serverChannel = ServerSocketChannel.open();

            // 2. 从 ServerSocketChannel里获取一个对于的 socket
            serverSocket = serverChannel.socket();

            // 3. 生成一个 Selector
            selector = Selector.open();

            // 4. 把 socket 绑定到端口上
            serverSocket.bind(new InetSocketAddress(iport));

            // 5. serverChannel 未非bolck
            serverChannel.configureBlocking(false);

            // 6. 通过Selector注册ServerSocketChannel: 只能注册 accept
            // 而SocketChannel可以注册CONNENCT,READ,WRITE ; register -> validOps
            // 在各个子类实现不同
            serverChannel.register(selector, SelectionKey.OP_ACCEPT);
            while (true) {
			try {
				// 获得IO准备就绪的channel数量
				int n = selector.select();

				// 没有channel准备就绪,继续执行
				if (n == 0) {
					continue;
				}

				// 用一个iterator返回Selector的selectedkeys
				Iterator it = selector.selectedKeys().iterator();

				// 处理每一个SelectionKey
				while (it.hasNext()) {
					SelectionKey key = (SelectionKey) it.next();

					// 判断是否有新的连接到达
					if (key.isAcceptable()) {
						
						// 返回SelectionKey的ServerSocketChannel
						ServerSocketChannel server = (ServerSocketChannel) key
								.channel();
						System.out.println("有连接");
						SocketChannel channel = server.accept();
						
						registerChannel(selector, channel, SelectionKey.OP_READ);
						
						doWork(channel);
					}

					// 判断是否有数据在此channel里需要读取
					if (key.isReadable()) {
						processData(key);
					}
				}

				// 删除 selectedkeys
				it.remove();

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

 

 

 

 客户端:

 

 

  //打开socket通道
		SocketChannel socketChannel = SocketChannel.open();
		//设置非阻塞方式
		socketChannel.configureBlocking(false);
		//打开选择器
		Selector selector = Selector.open();
		//注册连接到服务器socket动作
		socketChannel.register(selector, SelectionKey.OP_CONNECT);
		//连接
		socketChannel.connect( new InetSocketAddress("localhost",9988));
		
		Set<SelectionKey> selectkeySets;
		SelectionKey selectionKey;
		Iterator<SelectionKey> iterator;
		
		//与服务器通信通道
		SocketChannel clientChannel ;

	       while(true){
			//选择一组建,其相应的通道已为I/O操作准备就绪
			//此方法执行处于阻塞模式的选择操作
			selector.select(TIME_OUT);
			
			//返回此选择器的已选择键集。
			selectkeySets = selector.selectedKeys();
			iterator = selectkeySets.iterator();
			
			
			while(iterator.hasNext()){
				selectionKey = iterator.next();
				
				if (selectionKey.isConnectable()) {
                                  clientChannel = (SocketChannel)selectionKey.channel();
					// 判断此通道上是否正在进行连接操作。  
                                  // 完成套接字通道的连接过程。  
					if (clientChannel.isConnectionPending()) {//判断此通道上是否正在进行连接操作
						clientChannel.finishConnect();  //完成套接字通道的连接过程
                                   
                                  }
                                  clientChannel.register(selector, SelectionKey.OP_WRITE);
                            }else if (selectionKey.isReadable()) {
					clientChannel = (SocketChannel)selectionKey.channel();
					//将缓冲区清空
					receiveBuffer.clear();
					//读取服务器发送来的数据库到缓冲区
					count = clientChannel.read(receiveBuffer);//count 读取到的字节数
					if (count > 0) {
						clientChannel.register(selector, SelectionKey.OP_WRITE);
					}
                            }else if (selectionKey.isWritable()) {
					sendBuffer.clear();
					clientChannel = (SocketChannel)selectionKey.channel();
					clientChannel.write(sendBuffer);
					System.out.println("客户端向服务器发送数据:"+sendText);
					clientChannel.register(selector, SelectionKey.OP_READ);
                            }
                     }
                 }

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics