看到标题,您可能觉得,这跟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原创,转载请务必注明作者和原始出处。
本文地址:链接地址