在做关于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!
原文地址:https://www.cnblogs.com/Meiwah/p/10416092.html