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