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

    客户端代码如下:

  • 相关阅读:
    MySQL索引管理及执行计划
    MySQL客户端工具及SQL讲解
    mysql数据类型
    mysq日志管理
    mysql连接管理及实例初始化配置
    mysql用户权限管理
    msyql5.6与mysql5.7安装区别
    mysql简介
    ASP.NET使用ImageMap控件
    ASP.NET Calendar(日历控件)
  • 原文地址:https://www.cnblogs.com/love-jishu/p/3921708.html
Copyright © 2020-2023  润新知