java nio socket實例


Server端代碼:

public class NioServer {
    //通道管理器
    private Selector selector;
    
    //獲取一個ServerSocket通道,並初始化通道
    public NioServer init(int port) throws IOException{
        //獲取一個ServerSocket通道
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        serverChannel.configureBlocking(false);
        serverChannel.socket().bind(new InetSocketAddress(port));
        //獲取通道管理器
        selector=Selector.open();
        //將通道管理器與通道綁定,並為該通道注冊SelectionKey.OP_ACCEPT事件,
        //只有當該事件到達時,Selector.select()會返回,否則一直阻塞。
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        return this;
    }
    
    public void listen() throws IOException{
        System.out.println("服務器端啟動成功");
        
        //使用輪詢訪問selector
        while(true){
            //當有注冊的事件到達時,方法返回,否則阻塞。
            selector.select();
            
            //獲取selector中的迭代器,選中項為注冊的事件
            Iterator<SelectionKey> ite=selector.selectedKeys().iterator();
            
            while(ite.hasNext()){
                SelectionKey key = ite.next();
                //刪除已選key,防止重復處理
                ite.remove();
                //客戶端請求連接事件
                if(key.isAcceptable()){
                    ServerSocketChannel server = (ServerSocketChannel)key.channel();
                    //獲得客戶端連接通道
                    SocketChannel channel = server.accept();
                    channel.configureBlocking(false);
                    //向客戶端發消息
                    channel.write(ByteBuffer.wrap(new String("send message to client").getBytes()));
                    //在與客戶端連接成功后,為客戶端通道注冊SelectionKey.OP_READ事件。
                    channel.register(selector, SelectionKey.OP_READ);
                    
                    System.out.println("客戶端請求連接事件");
                }else if(key.isReadable()){//有可讀數據事件
                    //獲取客戶端傳輸數據可讀取消息通道。
                    SocketChannel channel = (SocketChannel)key.channel();
                    //創建讀取數據緩沖器
                    ByteBuffer buffer = ByteBuffer.allocate(10);
                    int read = channel.read(buffer);
                    byte[] data = buffer.array();
                    String message = new String(data);
                    
                    System.out.println("receive message from client, size:" + buffer.position() + " msg: " + message);
//                    ByteBuffer outbuffer = ByteBuffer.wrap(("server.".concat(msg)).getBytes());
//                    channel.write(outbuffer);
                }
            }
        }
    }
    
    public static void main(String[] args) throws IOException {
        new NioServer().init(9981).listen();
    }
}

Client端代碼:

public class NioClient {
    //管道管理器
    private Selector selector;
    
    public NioClient init(String serverIp, int port) throws IOException{
        //獲取socket通道
        SocketChannel channel = SocketChannel.open();
        
        channel.configureBlocking(false);
        //獲得通道管理器
        selector=Selector.open();
        
        //客戶端連接服務器,需要調用channel.finishConnect();才能實際完成連接。
        channel.connect(new InetSocketAddress(serverIp, port));
        //為該通道注冊SelectionKey.OP_CONNECT事件
        channel.register(selector, SelectionKey.OP_CONNECT);
        return this;
    }
    
    public void listen() throws IOException{
        System.out.println("客戶端啟動");
        //輪詢訪問selector
        while(true){
            //選擇注冊過的io操作的事件(第一次為SelectionKey.OP_CONNECT)
            selector.select();
            Iterator<SelectionKey> ite = selector.selectedKeys().iterator();
            while(ite.hasNext()){
                SelectionKey key = ite.next();
                //刪除已選的key,防止重復處理
                ite.remove();
                if(key.isConnectable()){
                    SocketChannel channel=(SocketChannel)key.channel();
                    
                    //如果正在連接,則完成連接
                    if(channel.isConnectionPending()){
                        channel.finishConnect();
                    }
                    
                    channel.configureBlocking(false);
                    //向服務器發送消息
                    channel.write(ByteBuffer.wrap(new String("send message to server.").getBytes()));
                    
                    //連接成功后,注冊接收服務器消息的事件
                    channel.register(selector, SelectionKey.OP_READ);
                    System.out.println("客戶端連接成功");
                }else if(key.isReadable()){ //有可讀數據事件。
                    SocketChannel channel = (SocketChannel)key.channel();
                    
                    ByteBuffer buffer = ByteBuffer.allocate(10);
                    channel.read(buffer);
                    byte[] data = buffer.array();
                    String message = new String(data);
                    
                    System.out.println("recevie message from server:, size:" + buffer.position() + " msg: " + message);
//                    ByteBuffer outbuffer = ByteBuffer.wrap(("client.".concat(msg)).getBytes());
//                    channel.write(outbuffer);
                }
            }
        }
    }
    
    public static void main(String[] args) throws IOException {
        new NioClient().init("127.0.0.1", 9981).listen();
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM