zoukankan      html  css  js  c++  java
  • Java NIO 网络编程基础

    Java NIO提供了一套网络api,可以用来处理连接数很多的情况。他的基本思想就是用一个线程来处理多个channel。
    nio selector

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    package geym.nio;

    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.net.ServerSocket;
    import java.nio.ByteBuffer;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.util.Iterator;
    import java.util.Set;

    public class MyServer {
        public static void main(String args[]throws Exception  
        {  
            MyServer server new MyServer(8080);  
            server.listen();  
        }  
      
        // 接受和发送数据缓冲区  
        private ByteBuffer send = ByteBuffer.allocate(1024);  
        private ByteBuffer receive = ByteBuffer.allocate(1024);  
      
        public int port 0;  
      
        ServerSocketChannel ssc null;  
      
        Selector selector null;  
      
        public MyServer(int portthrows Exception  
        {  
            // 打开服务器套接字通道  
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();  
            // 服务器配置为非阻塞  
            serverSocketChannel.configureBlocking(false);  
            // 检索与此通道关联的服务器套接字  
            ServerSocket serverSocket = serverSocketChannel.socket();  
            // 套接字的地址端口绑定
            serverSocket.bind(new InetSocketAddress(port));  
            // 通过open()方法找到Selector  
            selector = Selector.open();  
      
            // 注册到selector,等待连接  
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);  
            System.out.println("Server Start----8888:");  
              
            // 向发送缓冲区加入数据  
            send.put("data come from server".getBytes());  
        }  
      
        // 监听  
        private void listen(throws IOException  
        {  
            while (true)  
            {  
                // 等待一个连接,可能会返回多个key
                int count=selector.select();
                System.out.println("count="+count);
                // 返回此选择器的已选择键集。  
                Set<SelectionKey> selectionKeys = selector.selectedKeys();  
                Iterator<SelectionKey> iterator = selectionKeys.iterator();  
                while (iterator.hasNext())  
                {  
                    SelectionKey selectionKey = iterator.next();  
      
                    // 这里记得手动的把他remove掉,不然selector中的selectedKeys集合不会自动去除  
                    iterator.remove();  
                    handle(selectionKey);  
                }  
            }  
        }  
      
        // 处理请求  
        private void handle(SelectionKey selectionKeythrows IOException  
        {  
      
            ServerSocketChannel server null;  
            SocketChannel client null;  
            String receiveText;  
            String sendText;  
            int count 0;  
      
            // 测试此键的通道是否已准备好接受新的套接字连接。  
            if (selectionKey.isAcceptable())  
            {  
                System.out.println("selectionKey.isAcceptable()");
                // 返回为之创建此键的通道。  
                server (ServerSocketChannel) selectionKey.channel();  
      
                // 此方法返回的套接字通道(如果有)将处于阻塞模式。  
                client = server.accept();  
                // 配置为非阻塞  
                client.configureBlocking(false);  
                // 注册到selector,等待连接  
                client.register(selector, SelectionKey.OP_READ  
                        | SelectionKey.OP_WRITE);  
            }  
            else  
                if (selectionKey.isReadable())  
                {  
                    System.out.println("selectionKey.isReadable()");
                    // 返回为之创建此键的通道。  
                    client (SocketChannel) selectionKey.channel();  
                    // 将缓冲区清空以备下次读取  
                    receive.clear();  
                    // 读取服务器发送来的数据到缓冲区中  
                    client.read(receive);  
      
    //                System.out.println(new String(receive.array()));  
                      
                    selectionKey.interestOps(SelectionKey.OP_WRITE);  
                }  
                else  
                    if (selectionKey.isWritable())  
                    {  
                        System.out.println("selectionKey.isWritable()");
                        // 将缓冲区清空以备下次写入  
                        send.flip();  
                        // 返回为之创建此键的通道。  
                        client (SocketChannel) selectionKey.channel();  
      
                        // 输出到通道  
                        client.write(send);  
                          
    //                    selectionKey.interestOps(SelectionKey.OP_READ);  
                    }  
        
    }

    客户端代码如下:

  • 相关阅读:
    C++ 函数返回局部变量的std::move()的适用场景(转)
    Android 内存泄漏总结(转)
    android JNI调用(Android Studio 3.0.1)(转)
    Linux c —— opendir函数和readdir函数内涵及用法(转)
    理解Android编译命令(转)
    Linux内存管理(转)
    Android内存分析命令(转)
    关于跳板机穿透的文章 (未验证)
    windows下 git配置ssh
    转: Git远程操作详解 (阮一峰)
  • 原文地址:https://www.cnblogs.com/love-jishu/p/3921708.html
Copyright © 2011-2022 走看看