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.net.InetSocketAddress;
23 import java.net.SocketAddress;
24 import java.nio.channels.SelectionKey;
25 import java.nio.channels.Selector;
26 import java.nio.channels.SocketChannel;
27 import java.util.Collection;
28 import java.util.Iterator;
29 import java.util.concurrent.Executor;
30
31 import org.apache.mina.common.AbstractPollingIoConnector;
32 import org.apache.mina.common.IoConnector;
33 import org.apache.mina.common.IoProcessor;
34 import org.apache.mina.common.TransportMetadata;
35 import org.apache.mina.transport.socket.DefaultSocketSessionConfig;
36 import org.apache.mina.transport.socket.SocketConnector;
37 import org.apache.mina.transport.socket.SocketSessionConfig;
38
39
40
41
42
43
44
45 public final class NioSocketConnector
46 extends AbstractPollingIoConnector<NioSession, SocketChannel>
47 implements SocketConnector {
48
49 private volatile Selector selector;
50
51 public NioSocketConnector() {
52 super(new DefaultSocketSessionConfig(), NioProcessor.class);
53 }
54
55 public NioSocketConnector(int processorCount) {
56 super(new DefaultSocketSessionConfig(), NioProcessor.class, processorCount);
57 }
58
59 public NioSocketConnector(IoProcessor<NioSession> processor) {
60 super(new DefaultSocketSessionConfig(), processor);
61 }
62
63 public NioSocketConnector(Executor executor, IoProcessor<NioSession> processor) {
64 super(new DefaultSocketSessionConfig(), executor, processor);
65 }
66
67 @Override
68 protected void init() throws Exception {
69 this.selector = Selector.open();
70 }
71
72 @Override
73 protected void destroy() throws Exception {
74 if (selector != null) {
75 selector.close();
76 }
77 }
78
79 public TransportMetadata getTransportMetadata() {
80 return NioSocketSession.METADATA;
81 }
82
83 @Override
84 public SocketSessionConfig getSessionConfig() {
85 return (SocketSessionConfig) super.getSessionConfig();
86 }
87
88 @Override
89 public InetSocketAddress getDefaultRemoteAddress() {
90 return (InetSocketAddress) super.getDefaultRemoteAddress();
91 }
92
93 public void setDefaultRemoteAddress(InetSocketAddress defaultRemoteAddress) {
94 super.setDefaultRemoteAddress(defaultRemoteAddress);
95 }
96
97 @Override
98 protected Iterator<SocketChannel> allHandles() {
99 return new SocketChannelIterator(selector.keys());
100 }
101
102 @Override
103 protected boolean connect(SocketChannel handle, SocketAddress remoteAddress)
104 throws Exception {
105 return handle.connect(remoteAddress);
106 }
107
108 @Override
109 protected ConnectionRequest connectionRequest(SocketChannel handle) {
110 SelectionKey key = handle.keyFor(selector);
111 if (key == null) {
112 return null;
113 }
114
115 return (ConnectionRequest) key.attachment();
116 }
117
118 @Override
119 protected void close(SocketChannel handle) throws Exception {
120 SelectionKey key = handle.keyFor(selector);
121 if (key != null) {
122 key.cancel();
123 }
124 handle.close();
125 }
126
127 @Override
128 protected boolean finishConnect(SocketChannel handle) throws Exception {
129 SelectionKey key = handle.keyFor(selector);
130 if (handle.finishConnect()) {
131 if (key != null) {
132 key.cancel();
133 }
134 return true;
135 }
136
137 return false;
138 }
139
140 @Override
141 protected SocketChannel newHandle(SocketAddress localAddress)
142 throws Exception {
143 SocketChannel ch = SocketChannel.open();
144 ch.socket().setReuseAddress(true);
145 if (localAddress != null) {
146 ch.socket().bind(localAddress);
147 }
148 ch.configureBlocking(false);
149 return ch;
150 }
151
152 @Override
153 protected NioSession newSession(IoProcessor<NioSession> processor, SocketChannel handle) {
154 return new NioSocketSession(this, processor, handle);
155 }
156
157 @Override
158 protected void register(SocketChannel handle, ConnectionRequest request)
159 throws Exception {
160 handle.register(selector, SelectionKey.OP_CONNECT, request);
161 }
162
163 @Override
164 protected boolean select(int timeout) throws Exception {
165 return selector.select(timeout) > 0;
166 }
167
168 @Override
169 protected Iterator<SocketChannel> selectedHandles() {
170 return new SocketChannelIterator(selector.selectedKeys());
171 }
172
173 @Override
174 protected void wakeup() {
175 selector.wakeup();
176 }
177
178 private static class SocketChannelIterator implements Iterator<SocketChannel> {
179
180 private final Iterator<SelectionKey> i;
181
182 private SocketChannelIterator(Collection<SelectionKey> selectedKeys) {
183 this.i = selectedKeys.iterator();
184 }
185
186 public boolean hasNext() {
187 return i.hasNext();
188 }
189
190 public SocketChannel next() {
191 SelectionKey key = i.next();
192 return (SocketChannel) key.channel();
193 }
194
195 public void remove() {
196 i.remove();
197 }
198 }
199 }