• 在做关于NIO TCP编程小案例时遇到无法监听write的问题,没想到只是我的if语句的位置放错了位置,哎,看了半天没看出来


    在做关于NIO TCP编程小案例时遇到无法监听write的问题,没想到只是我的if语句的位置放错了位置,哎,看了半天没看出来

    贴下课堂笔记

    Java中使用NIO进行网络TCP套接字编程主要以下几个类:

    ServerSocketChannel: 服务端套接字通道,主要监听接收客户端请求

    Selector:通道选择器,主要用于管理服务端通道和所有客户端通道(监听通道中发生的事件),也就说是一个多路通道复用器。

    SelectorKey: 事件选择键

    SocketChannel: 套接字通道(客户端)

    这篇文章《NIO编程中的SelectionKey.interestOps方法中的逻辑运算》解决了我一些疑问,地址:https://blog.csdn.net/woaiqianzhige/article/details/78696188

    NIO 套接字服务端开发步骤:

    1. 创建选择器
    2. 启动服务端通道
    3. 设置服务端通道为非阻塞模式
    4. 将服务端通道注册到选择器
    5. 轮训通道事件
    6. 处理通道事件
    7. 关闭通道(可选)

    案例:服务端接收客户端发送的短信息,服务端回复已收到。

    服务端代码:

      1 import java.io.IOException;
      2 import java.net.InetSocketAddress;
      3 import java.nio.ByteBuffer;
      4 import java.nio.channels.ClosedChannelException;
      5 import java.nio.channels.SelectionKey;
      6 import java.nio.channels.Selector;
      7 import java.nio.channels.ServerSocketChannel;
      8 import java.nio.channels.SocketChannel;
      9 import java.util.Iterator;
     10 import java.util.Set;
     11 
     12 public class Server {
     13     private Selector selector;
     14     private ServerSocketChannel serverSocketChannel;
     15     private ByteBuffer byteBuffer = ByteBuffer.allocate(8192);
     16 
     17     /**
     18      * 构造方法 启动服务器
     19      * 
     20      * @param port
     21      * @throws IOException
     22      */
     23     public Server() {
     24         try {
     25             selector = Selector.open();
     26             serverSocketChannel = ServerSocketChannel.open();
     27             serverSocketChannel.configureBlocking(false);
     28             serverSocketChannel.bind(new InetSocketAddress(10086));
     29             serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
     30             System.out.println("Server start successful with port: 10086");
     31         } catch (ClosedChannelException e) {
     32             e.printStackTrace();
     33         } catch (IOException e) {
     34             e.printStackTrace();
     35         }
     36     }
     37 
     38     public static void main(String[] args) throws Exception {
     39         new Server().start();
     40     }
     41 
     42     private void start() {
     43         while (true) {
     44             try {
     45                 selector.select();
     46                 Set<SelectionKey> keys = selector.selectedKeys();
     47                 Iterator<SelectionKey> keyIterator = keys.iterator();
     48                 while (keyIterator.hasNext()) {
     49                     SelectionKey key = keyIterator.next();
     50                     keyIterator.remove();
     51                     if (!key.isValid()) {
     52                         continue;
     53                     }
     54                     if (key.isAcceptable()) {
     55                         accept(key);
     56                     }
     57                     if (key.isReadable()) {
     58                         receive(key);
     59                     }
     60                     if (key.isWritable()) {
     61                         reply(key);
     62                     }
     63                 }
     64             } catch (IOException e) {
     65                 e.printStackTrace();
     66             } catch (Exception e) {
     67                 e.printStackTrace();
     68             }
     69         }
     70     }
     71 
     72     private void reply(SelectionKey key) {
     73         try {
     74             SocketChannel socketChannel = (SocketChannel) key.channel();
     75             byteBuffer.clear();
     76             String message = "receive success";
     77             byteBuffer.put(message.getBytes());
     78             byteBuffer.flip();
     79             socketChannel.write(byteBuffer);
     80             System.out.println("reply:" + message);
     81             byteBuffer.clear();
     82             key.interestOps(SelectionKey.OP_READ);
     83         } catch (IOException e) {
     84             e.printStackTrace();
     85         }
     86     }
     87 
     88     private void receive(SelectionKey key) {
     89         try {
     90             SocketChannel socketChannel = (SocketChannel) key.channel();
     91             byteBuffer.clear();
     92             int flag = socketChannel.read(byteBuffer);
     93             if (flag == -1) {
     94                 key.channel().close();
     95                 key.cancel();
     96                 return;
     97             }
     98             byteBuffer.flip();
     99             byte[] buf = new byte[byteBuffer.remaining()];
    100             byteBuffer.get(buf);
    101             String message = new String(buf);
    102             System.out.println("receive message:" + message);
    103             byteBuffer.clear();
    104             key.interestOps(SelectionKey.OP_WRITE);
    105         } catch (IOException e) {
    106             e.printStackTrace();
    107         }
    108     }
    109 
    110     private void accept(SelectionKey key) {
    111         try {
    112             SocketChannel socketChannel = serverSocketChannel.accept();
    113             socketChannel.configureBlocking(false);
    114             socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
    115             System.out.println(Thread.currentThread().getName() + ": create client channel.");
    116         } catch (ClosedChannelException e) {
    117             e.printStackTrace();
    118         } catch (IOException e) {
    119             e.printStackTrace();
    120         }
    121     }
    122 }

    客户端代码:

     1 import java.io.IOException;
     2 import java.net.InetSocketAddress;
     3 import java.nio.ByteBuffer;
     4 import java.nio.channels.ClosedChannelException;
     5 import java.nio.channels.SelectionKey;
     6 import java.nio.channels.Selector;
     7 import java.nio.channels.SocketChannel;
     8 import java.util.Iterator;
     9 import java.util.Scanner;
    10 
    11 public class Client {
    12     private Selector selector;
    13     private ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
    14     private SocketChannel socketChannel;
    15 
    16     public Client() {
    17         try {
    18             selector = Selector.open();
    19             socketChannel = SocketChannel.open();
    20             socketChannel.configureBlocking(false);
    21             socketChannel.register(selector, SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE);
    22             socketChannel.connect(new InetSocketAddress("127.0.0.1", 10086));
    23             System.out.println("Client start successful");
    24         } catch (ClosedChannelException e) {
    25             e.printStackTrace();
    26         } catch (IOException e) {
    27             e.printStackTrace();
    28         }
    29     }
    30 
    31     public static void main(String[] args) {
    32         new Client().start();    
    33     }
    34 
    35     private void start() {
    36         while (true) {
    37             try {
    38                 selector.select();
    39                 Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
    40                 while (keys.hasNext()) {
    41                     SelectionKey key = keys.next();
    42                     keys.remove();
    43                     if (!key.isValid()) {
    44                         continue;
    45                     }
    46                     if (key.isConnectable()) {
    47                         if (socketChannel.finishConnect()) {
    48                             key.interestOps(key.interestOps() & ~SelectionKey.OP_CONNECT);
    49                             System.out.println("Client connect server success");
    50                         }
    51                     }
    52                     if (key.isReadable()) {
    53                         receive(key);
    54                     }
    55                     if (key.isWritable()) {
    56                         reply(key);
    57                     }
    58                 }
    59             } catch (Exception e) {
    60                 e.printStackTrace();
    61             }
    62         }
    63     }
    64 
    65     private void reply(SelectionKey key) {
    66         try {
    67             @SuppressWarnings("resource")
    68             Scanner scanner = new Scanner(System.in);
    69             byteBuffer.clear();
    70             System.out.println("please input message:");
    71             String message = scanner.next();
    72             byteBuffer.put(message.getBytes());
    73             byteBuffer.flip();
    74             socketChannel.write(byteBuffer);
    75             byteBuffer.clear();
    76             System.out.println("send message:" + message);
    77             key.interestOps(SelectionKey.OP_READ);
    78         } catch (IOException e) {
    79             e.printStackTrace();
    80         }
    81     }
    82 
    83     private void receive(SelectionKey key) {
    84         try {
    85             byteBuffer.clear();
    86             socketChannel.read(byteBuffer);
    87             byteBuffer.flip();
    88             byte[] bytes = new byte[byteBuffer.remaining()];
    89             byteBuffer.get(bytes);
    90             String message = new String(bytes).trim();
    91             System.out.println("receive message: " + message);
    92             byteBuffer.clear();
    93             key.interestOps(SelectionKey.OP_WRITE);
    94         } catch (IOException e) {
    95             e.printStackTrace();
    96         }
    97     }
    98 }

    真是粗心大意了。。。特发此博文给我自己涨涨记性

    Higher, faster, stronger!
  • 相关阅读:
    数据库的操作封装成类
    简单搭建WEB框架及原理
    界面小项目之小米商品排列
    界面小项目之小米登录注册
    kubernetes版本1.7.6对比1.13.0
    docker将宿主机文件复制到容器内
    常用git命令
    centos7常用命令汇总
    openstack相关的命令总结
    kubernetes常用命令2
  • 原文地址:https://www.cnblogs.com/Meiwah/p/10416092.html
Copyright © 2020-2023  润新知