Java NIO框架Netty教程(六)-Java NIO Selector模式

释放双眼,带上耳机,听听看~!

看到标题,您可能觉得,这跟Netty有什么关系呢?确实,如果你完全是使用Netty的,那么可能你可以完全不需要了解Selector。但是,不得不提的是,Netty底层关于NIO的实现也是基于Java的Selector的,是对Selector的封装。所以,我个人认为理解好Selector对于使用和理解Netty都是很多有帮助的。当然,如果您确实不关心这些,只想会用Netty就可以了。那么下文,您可以略过:)

笔者对于Selector也是新上手学习的。之前很多新人跟我交流,都会提到一个新框架或者一个新开源工具的使用和上手的问题。他们会觉得上手困难,耗费事件。不过笔者,从来没有此种感觉。这里正好,借用Selector的学习过程,跟大家交流一下,我上手的过程。

 

想要使用一个工具,自然是先了解其定位,解决问题的原理或者工作流程。所以,笔者先从网上了解了一下Selector大概的工作流程。

 

NIO 有一个主要的类Selector,这个类似一个观察者,只要我们把需要探知的socketchannel告诉Selector,我们接着做别的事情,当有事件发生时,他会通知我们,传回一组SelectionKey,我们读取这些Key,就会获得我们刚刚注册过的socketchannel,然后,我们从这个Channel中读取数据,放心,包准能够读到,接着我们可以处理这些数据。

 

这是笔者摘录的一小段总结,就这一小段基本已经可以说明问题了。接下来,我们要考虑的就是,要实现这个过程,我们需要做什么?顺着描述,我们可以想象,需要选择器,需要消息传送的通道,需要注册一个事件,用于识别。通道自然需要绑定到一个地址。有了这样大概的想法,我们就可以去API里找相关的接口。

 

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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
1/**
2        
3
4        
5
6
7           
8          * Java NIO Select模式服务端样例代码
9        
10
11        
12
13
14           
15          *  
16        
17
18        
19
20
21           
22          * @author lihzh
23        
24
25        
26
27
28           
29          * @alia OneCoder
30        
31
32        
33
34
35           
36          * @Blog  http://www.coderli.com
37        
38
39        
40
41
42           
43          * @date 2012-7-16 下午9:22:53
44        
45
46        
47
48
49           
50          */
51        
52
53        
54
55
56          public
57           class
58           NioSelectorServer {
59        
60
61        
62
63
64            
65        
66
67        
68
69
70              
71          /**
72        
73
74        
75
76
77               
78          * @author lihzh
79        
80
81        
82
83
84               
85          * @throws IOException
86        
87
88        
89
90
91               
92          * @alia OneCoder
93        
94
95        
96
97
98               
99          * @date 2012-7-16 下午9:22:53
100        
101
102        
103
104
105               
106          */
107        
108
109        
110
111
112              
113          public
114           static
115           void
116           main(String[] args)  
117          throws
118           IOException {
119        
120
121        
122
123
124                  
125          // 创建一个selector选择器
126        
127
128        
129
130
131                  
132          Selector selector = Selector.open();
133        
134
135        
136
137
138                  
139          // 打开一个通道
140        
141
142        
143
144
145                  
146          ServerSocketChannel socketChannel = ServerSocketChannel.open();
147        
148
149        
150
151
152                  
153          // 绑定到9000端口
154        
155
156        
157
158
159                  
160          socketChannel.socket().bind(
161          new
162           InetSocketAddress(
163          8000
164          ));
165        
166
167        
168
169
170                  
171          // 使设定non-blocking的方式。
172        
173
174        
175
176
177                  
178          socketChannel.configureBlocking(
179          false
180          );
181        
182
183        
184
185
186                  
187          // 向Selector注册Channel及我们有兴趣的事件
188        
189
190        
191
192
193                  
194          socketChannel.register(selector, SelectionKey.OP_ACCEPT);
195        
196
197        
198
199
200                  
201          for
202           (;;) {
203        
204
205        
206
207
208                      
209          // 选择事件
210        
211
212        
213
214
215                      
216          selector.select();
217        
218
219        
220
221
222                      
223          // 当有客户端准备连接到服务端时,便会出发请求
224        
225
226        
227
228
229                      
230          for
231           (Iterator<SelectionKey> keyIter = selector.selectedKeys()
232        
233
234        
235
236
237                              
238          .iterator(); keyIter.hasNext();) {
239        
240
241        
242
243
244                          
245          SelectionKey key = keyIter.next();
246        
247
248        
249
250
251                          
252          keyIter.remove();
253        
254
255        
256
257
258                          
259          System.out.println(key.readyOps());
260        
261
262        
263
264
265                          
266          if
267           (key.isAcceptable()) {
268        
269
270        
271
272
273                              
274          System.out.println(
275          "Accept"
276          );
277        
278
279        
280
281
282                              
283          // 接受连接到此Channel的连接
284        
285
286        
287
288
289                              
290          socketChannel.accept();
291        
292
293        
294
295
296                          
297          }
298        
299
300        
301
302
303                      
304          }
305        
306
307        
308
309
310                  
311          }
312        
313
314        
315
316
317              
318          }
319        
320
321        
322
323
324          }
325

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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
1/**
2        
3
4        
5
6
7           
8          * Java NIO Selector模式,客户端代码
9        
10
11        
12
13
14           
15          *  
16        
17
18        
19
20
21           
22          * @author lihzh
23        
24
25        
26
27
28           
29          * @alia OneCoder
30        
31
32        
33
34
35           
36          * @blog  http://www.coderli.com
37        
38
39        
40
41
42           
43          */
44        
45
46        
47
48
49          public
50           class
51           NioSelectorClient {
52        
53
54        
55
56
57            
58        
59
60        
61
62
63              
64          /**
65        
66
67        
68
69
70               
71          * @author lihzh
72        
73
74        
75
76
77               
78          * @throws IOException  
79        
80
81        
82
83
84               
85          * @alia OneCoder
86        
87
88        
89
90
91               
92          */
93        
94
95        
96
97
98              
99          public
100           static
101           void
102           main(String[] args)  
103          throws
104           IOException {
105        
106
107        
108
109
110                  
111          SocketChannel channel = SocketChannel.open();
112        
113
114        
115
116
117                  
118          channel.configureBlocking(
119          false
120          );
121        
122
123        
124
125
126                  
127          channel.connect(
128          new
129           InetSocketAddress(
130          "127.0.0.1"
131          ,  
132          8000
133          ));
134        
135
136        
137
138
139              
140          }
141        
142
143        
144
145
146          }
147

代码很简单,服务端接受到客户端的连接请求后,会打印出"Accept"信息。

 

简单概括就是,整一个通道,通道加个选择过滤器,看来的事件是不是我想要的,不想要的干脆不管,想要的,我就存起来,留着慢慢处理。

 

现在感觉是不是Netty确实跟这个机制比较想,如果让你去实现Netty先有的功能,也有思路可想了吧。

 

如非特别注明,本站内容均为OneCoder原创,转载请务必注明作者和原始出处。

本文地址:链接地址

给TA打赏
共{{data.count}}人
人已打赏
安全技术

详解Node.js API系列 Http模块(2) CNodejs爬虫实现

2021-12-21 16:36:11

安全技术

从零搭建自己的SpringBoot后台框架(二十三)

2022-1-12 12:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索