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);  
                    }  
        
    }

    客户端代码如下:

  • 相关阅读:
    Java 内存溢出(java.lang.OutOfMemoryError)的常见情况和处理方式总结
    Springmvc bean依赖注入为空
    protocol Buffer
    SSO单点登录
    .gitignore 不生效问题
    IntelliJ IDEA 背景色以及字体设置
    zookeeper 集群
    zookeeper 下载安装
    springboot 连接redis
    xshell 连接redis
  • 原文地址:https://www.cnblogs.com/love-jishu/p/3921708.html
Copyright © 2011-2022 走看看