1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.transport.socket.nio;
21
22 import java.io.IOException;
23 import java.net.InetSocketAddress;
24 import java.net.ServerSocket;
25 import java.net.SocketAddress;
26 import java.nio.channels.ClosedSelectorException;
27 import java.nio.channels.SelectionKey;
28 import java.nio.channels.Selector;
29 import java.nio.channels.ServerSocketChannel;
30 import java.nio.channels.SocketChannel;
31 import java.util.Collection;
32 import java.util.Iterator;
33 import java.util.concurrent.Executor;
34
35 import org.apache.mina.core.polling.AbstractPollingIoAcceptor;
36 import org.apache.mina.core.service.IoAcceptor;
37 import org.apache.mina.core.service.IoProcessor;
38 import org.apache.mina.core.service.IoService;
39 import org.apache.mina.core.service.SimpleIoProcessorPool;
40 import org.apache.mina.core.service.TransportMetadata;
41 import org.apache.mina.transport.socket.DefaultSocketSessionConfig;
42 import org.apache.mina.transport.socket.SocketAcceptor;
43 import org.apache.mina.transport.socket.SocketSessionConfig;
44
45
46
47
48
49
50
51 public final class NioSocketAcceptor extends AbstractPollingIoAcceptor<NioSession, ServerSocketChannel> implements
52 SocketAcceptor {
53
54 private volatile Selector selector;
55
56
57
58
59 public NioSocketAcceptor() {
60 super(new DefaultSocketSessionConfig(), NioProcessor.class);
61 ((DefaultSocketSessionConfig) getSessionConfig()).init(this);
62 }
63
64
65
66
67
68
69
70
71 public NioSocketAcceptor(int processorCount) {
72 super(new DefaultSocketSessionConfig(), NioProcessor.class, processorCount);
73 ((DefaultSocketSessionConfig) getSessionConfig()).init(this);
74 }
75
76
77
78
79
80
81
82 public NioSocketAcceptor(IoProcessor<NioSession> processor) {
83 super(new DefaultSocketSessionConfig(), processor);
84 ((DefaultSocketSessionConfig) getSessionConfig()).init(this);
85 }
86
87
88
89
90
91
92
93
94 public NioSocketAcceptor(Executor executor, IoProcessor<NioSession> processor) {
95 super(new DefaultSocketSessionConfig(), executor, processor);
96 ((DefaultSocketSessionConfig) getSessionConfig()).init(this);
97 }
98
99
100
101
102 @Override
103 protected void init() throws Exception {
104 selector = Selector.open();
105 }
106
107
108
109
110 @Override
111 protected void destroy() throws Exception {
112 if (selector != null) {
113 selector.close();
114 }
115 }
116
117
118
119
120 public TransportMetadata getTransportMetadata() {
121 return NioSocketSession.METADATA;
122 }
123
124
125
126
127 @Override
128 public SocketSessionConfig getSessionConfig() {
129 return (SocketSessionConfig) super.getSessionConfig();
130 }
131
132
133
134
135 @Override
136 public InetSocketAddress getLocalAddress() {
137 return (InetSocketAddress) super.getLocalAddress();
138 }
139
140
141
142
143 @Override
144 public InetSocketAddress getDefaultLocalAddress() {
145 return (InetSocketAddress) super.getDefaultLocalAddress();
146 }
147
148
149
150
151 public void setDefaultLocalAddress(InetSocketAddress localAddress) {
152 setDefaultLocalAddress((SocketAddress) localAddress);
153 }
154
155
156
157
158 @Override
159 protected NioSession accept(IoProcessor<NioSession> processor, ServerSocketChannel handle) throws Exception {
160
161 SelectionKey key = handle.keyFor(selector);
162
163 if ((key == null) || (!key.isValid()) || (!key.isAcceptable())) {
164 return null;
165 }
166
167
168 SocketChannel ch = handle.accept();
169
170 if (ch == null) {
171 return null;
172 }
173
174 return new NioSocketSession(this, processor, ch);
175 }
176
177
178
179
180 @Override
181 protected ServerSocketChannel open(SocketAddress localAddress) throws Exception {
182
183 ServerSocketChannel channel = ServerSocketChannel.open();
184
185 boolean success = false;
186
187 try {
188
189 channel.configureBlocking(false);
190
191
192 ServerSocket socket = channel.socket();
193
194
195 socket.setReuseAddress(isReuseAddress());
196
197
198 socket.bind(localAddress, getBacklog());
199
200
201 channel.register(selector, SelectionKey.OP_ACCEPT);
202 success = true;
203 } finally {
204 if (!success) {
205 close(channel);
206 }
207 }
208 return channel;
209 }
210
211
212
213
214 @Override
215 protected SocketAddress localAddress(ServerSocketChannel handle) throws Exception {
216 return handle.socket().getLocalSocketAddress();
217 }
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232 @Override
233 protected int select() throws Exception {
234 return selector.select();
235 }
236
237
238
239
240 @Override
241 protected Iterator<ServerSocketChannel> selectedHandles() {
242 return new ServerSocketChannelIterator(selector.selectedKeys());
243 }
244
245
246
247
248 @Override
249 protected void close(ServerSocketChannel handle) throws Exception {
250 SelectionKey key = handle.keyFor(selector);
251
252 if (key != null) {
253 key.cancel();
254 }
255
256 handle.close();
257 }
258
259
260
261
262 @Override
263 protected void wakeup() {
264 selector.wakeup();
265 }
266
267
268
269
270
271 private static class ServerSocketChannelIterator implements Iterator<ServerSocketChannel> {
272
273 private final Iterator<SelectionKey> iterator;
274
275
276
277
278
279
280
281 private ServerSocketChannelIterator(Collection<SelectionKey> selectedKeys) {
282 iterator = selectedKeys.iterator();
283 }
284
285
286
287
288
289
290 public boolean hasNext() {
291 return iterator.hasNext();
292 }
293
294
295
296
297
298
299
300 public ServerSocketChannel next() {
301 SelectionKey key = iterator.next();
302
303 if (key.isValid() && key.isAcceptable()) {
304 return (ServerSocketChannel) key.channel();
305 }
306
307 return null;
308 }
309
310
311
312
313 public void remove() {
314 iterator.remove();
315 }
316 }
317 }