NIO Socket

public class NIOServer {
    // 通道管理器(Selector)
    private static Selector selector;
 
    public static void main(String[] args) throws IOException {
        // 創建通道管理器(Selector)
        selector = Selector.open();
 
        // 創建通道ServerSocketChannel
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        // 將通道設置爲非阻塞
        serverSocketChannel.configureBlocking(false);
 
        // 將ServerSocketChannel對應的ServerSocket綁定到指定端口(port)
        ServerSocket serverSocket = serverSocketChannel.socket();
        serverSocket.bind(new InetSocketAddress(8989));
 
        /**
         * 將通道(Channel)註冊到通道管理器(Selector),併爲該通道註冊selectionKey.OP_ACCEPT事件
         * 註冊該事件後,當事件到達的時候,selector.select()會返回,
         * 如果事件沒有到達selector.select()會一直阻塞。
         */
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        // 循環處理
        while (true) {
        	try{
        		 // 當註冊事件到達時,方法返回,否則該方法會一直阻塞
                selector.select();
                // 獲取監聽事件
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> iterator = selectionKeys.iterator();
                // 迭代處理
                while (iterator.hasNext()) {
                    // 獲取事件
                    SelectionKey key = iterator.next();
                    // 客戶端請求連接事件,接受客戶端連接就緒
                    if (key.isAcceptable()) {
                    	acceptHandler(key);
                    } else if (key.isReadable()) {// 監聽到讀事件,對讀事件進行處理
                    	readHandler(key);
                    }
                    // 移除事件,避免重複處理
                    iterator.remove();
                }
        	}catch (Exception e) {
        		e.printStackTrace();
			}
        }
    }
 
    /**
     * 處理客戶端連接成功事件
     */
    private static void acceptHandler(SelectionKey key) throws IOException {
        // 獲取客戶端連接通道
        ServerSocketChannel server = (ServerSocketChannel) key.channel();
        SocketChannel socketChannel = server.accept();
        socketChannel.configureBlocking(false); // 設置非阻塞
        // 信息通過通道發送給客戶端
        socketChannel.write(ByteBuffer.wrap(new String("hello client , 撲街!!").getBytes()));
        // 給通道設置讀事件,客戶端監聽到讀事件後,進行讀取操作
        socketChannel.register(selector, SelectionKey.OP_READ);
    }
 
    /**
     * 監聽到讀事件,讀取客戶端發送過來的消息
     */
    private static void readHandler(SelectionKey key) throws IOException {
        SocketChannel channel = (SocketChannel) key.channel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        int count ;
        buffer.clear();
        try {
            while ((count = channel.read(buffer)) > 0) {
                buffer.flip();
                byte[] bytes = new byte[buffer.remaining()];
                buffer.get(bytes);
                System.out.println("讀取客戶端消息: " + new String(bytes));
            }
            if (count < 0) {
                channel.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
      
    }
}

 

public class NIOClient {
    public static void main(String[] args) throws IOException, InterruptedException {
        // 創建通道SocketChannel
        SocketChannel channel = SocketChannel.open();
        // 將通道設置爲非阻塞
        channel.configureBlocking(false);
        // 客戶端連接服務器,其實方法執行並沒有實現連接,
        // 需要在handleConnect方法中調channel.finishConnect()才能完成連接
        channel.connect(new InetSocketAddress("localhost", 8989));
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        while (!channel.finishConnect()) {
            TimeUnit.SECONDS.sleep(2);
            System.out.println("111111111111111111");
        }
        for (int i=0; i<5; i++) {
            TimeUnit.MICROSECONDS.sleep(2);
            String message = "send message " + i + " from" + "AAAAA";
            buffer.put(message.getBytes());
            buffer.flip();
            //buffer先把數據讀入到buffer,然後channel先把buffer中的數據寫入到channel,
            channel.write(buffer);
            buffer.clear();
        }
        
        {{
            ByteBuffer buffer2 = ByteBuffer.allocate(1024);
            int count ;
            buffer2.clear();
            try {
                while ((count = channel.read(buffer2)) > 0) {
                    buffer2.flip();
                    byte[] bytes = new byte[buffer2.remaining()];
                    buffer2.get(bytes);
                    System.out.println("讀取客戶端消息: " + new String(bytes));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }}
        channel.close();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章