zoukankan      html  css  js  c++  java
  • 在做关于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!
  • 相关阅读:
    hdu 1028 Ignatius and the Princess III (n的划分)
    CodeForces
    poj 3254 Corn Fields (状压DP入门)
    HYSBZ 1040 骑士 (基环外向树DP)
    PAT 1071 Speech Patterns (25)
    PAT 1077 Kuchiguse (20)
    PAT 1043 Is It a Binary Search Tree (25)
    PAT 1053 Path of Equal Weight (30)
    c++ 常用标准库
    常见数学问题
  • 原文地址:https://www.cnblogs.com/Meiwah/p/10416092.html
Copyright © 2011-2022 走看看