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