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.support;
21
22 import java.net.SocketAddress;
23 import java.net.SocketException;
24 import java.nio.channels.DatagramChannel;
25 import java.nio.channels.SelectionKey;
26 import java.util.Queue;
27 import java.util.concurrent.ConcurrentLinkedQueue;
28
29 import org.apache.mina.common.BroadcastIoSession;
30 import org.apache.mina.common.IoFilterChain;
31 import org.apache.mina.common.IoHandler;
32 import org.apache.mina.common.IoService;
33 import org.apache.mina.common.IoServiceConfig;
34 import org.apache.mina.common.IoSession;
35 import org.apache.mina.common.IoSessionConfig;
36 import org.apache.mina.common.RuntimeIOException;
37 import org.apache.mina.common.TransportType;
38 import org.apache.mina.common.WriteFuture;
39 import org.apache.mina.common.IoFilter.WriteRequest;
40 import org.apache.mina.common.support.BaseIoSession;
41 import org.apache.mina.transport.socket.nio.DatagramServiceConfig;
42 import org.apache.mina.transport.socket.nio.DatagramSessionConfig;
43
44
45
46
47
48
49
50 class DatagramSessionImpl extends BaseIoSession implements BroadcastIoSession {
51 private final IoService wrapperManager;
52
53 private final IoServiceConfig serviceConfig;
54
55 private final DatagramSessionConfig config = new SessionConfigImpl();
56
57 private final DatagramService managerDelegate;
58
59 private final DatagramFilterChain filterChain;
60
61 private final DatagramChannel ch;
62
63 private final Queue<WriteRequest> writeRequestQueue;
64
65 private final IoHandler handler;
66
67 private final SocketAddress localAddress;
68
69 private final SocketAddress serviceAddress;
70
71 private SocketAddress remoteAddress;
72
73 private SelectionKey key;
74
75 private int readBufferSize;
76
77
78
79
80 DatagramSessionImpl(IoService wrapperManager,
81 DatagramService managerDelegate, IoServiceConfig serviceConfig,
82 DatagramChannel ch, IoHandler defaultHandler,
83 SocketAddress serviceAddress, SocketAddress localAddress) {
84 this.wrapperManager = wrapperManager;
85 this.managerDelegate = managerDelegate;
86 this.filterChain = new DatagramFilterChain(this);
87 this.ch = ch;
88 this.writeRequestQueue = new ConcurrentLinkedQueue<WriteRequest>();
89 this.handler = defaultHandler;
90 this.remoteAddress = ch.socket().getRemoteSocketAddress();
91
92 this.serviceAddress = serviceAddress;
93 this.localAddress = localAddress;
94 this.serviceConfig = serviceConfig;
95
96
97 IoSessionConfig sessionConfig = serviceConfig.getSessionConfig();
98 if (sessionConfig instanceof DatagramSessionConfig) {
99 DatagramSessionConfig cfg = (DatagramSessionConfig) sessionConfig;
100 this.config.setBroadcast(cfg.isBroadcast());
101 this.config.setReceiveBufferSize(cfg.getReceiveBufferSize());
102 this.config.setReuseAddress(cfg.isReuseAddress());
103 this.config.setSendBufferSize(cfg.getSendBufferSize());
104
105 if (this.config.getTrafficClass() != cfg.getTrafficClass()) {
106 this.config.setTrafficClass(cfg.getTrafficClass());
107 }
108 }
109 }
110
111 public IoService getService() {
112 return wrapperManager;
113 }
114
115 public IoServiceConfig getServiceConfig() {
116 return serviceConfig;
117 }
118
119 public IoSessionConfig getConfig() {
120 return config;
121 }
122
123 DatagramService getManagerDelegate() {
124 return managerDelegate;
125 }
126
127 public IoFilterChain getFilterChain() {
128 return filterChain;
129 }
130
131 DatagramChannel getChannel() {
132 return ch;
133 }
134
135 SelectionKey getSelectionKey() {
136 return key;
137 }
138
139 void setSelectionKey(SelectionKey key) {
140 this.key = key;
141 }
142
143 public IoHandler getHandler() {
144 return handler;
145 }
146
147 @Override
148 protected void close0() {
149 IoServiceConfig config = getServiceConfig();
150 if (config instanceof DatagramServiceConfig) {
151 ((DatagramServiceConfig) config).getSessionRecycler().remove(this);
152 }
153 filterChain.fireFilterClose(this);
154 }
155
156 Queue<WriteRequest> getWriteRequestQueue() {
157 return writeRequestQueue;
158 }
159
160 @Override
161 protected void write0(WriteRequest writeRequest) {
162 filterChain.fireFilterWrite(this, writeRequest);
163 }
164
165 public TransportType getTransportType() {
166 return TransportType.DATAGRAM;
167 }
168
169 public SocketAddress getRemoteAddress() {
170 return remoteAddress;
171 }
172
173 void setRemoteAddress(SocketAddress remoteAddress) {
174 this.remoteAddress = remoteAddress;
175 }
176
177 public SocketAddress getLocalAddress() {
178 return localAddress;
179 }
180
181 public SocketAddress getServiceAddress() {
182 return serviceAddress;
183 }
184
185 @Override
186 protected void updateTrafficMask() {
187 managerDelegate.updateTrafficMask(this);
188 }
189
190 int getReadBufferSize() {
191 return readBufferSize;
192 }
193
194 private class SessionConfigImpl extends DatagramSessionConfigImpl implements
195 DatagramSessionConfig {
196 @Override
197 public int getReceiveBufferSize() {
198 try {
199 return ch.socket().getReceiveBufferSize();
200 } catch (SocketException e) {
201 throw new RuntimeIOException(e);
202 }
203 }
204
205 @Override
206 public void setReceiveBufferSize(int receiveBufferSize) {
207 if (DatagramSessionConfigImpl.isSetReceiveBufferSizeAvailable()) {
208 try {
209 ch.socket().setReceiveBufferSize(receiveBufferSize);
210
211 receiveBufferSize = ch.socket().getReceiveBufferSize();
212 DatagramSessionImpl.this.readBufferSize = receiveBufferSize;
213 } catch (SocketException e) {
214 throw new RuntimeIOException(e);
215 }
216 }
217 }
218
219 @Override
220 public boolean isBroadcast() {
221 try {
222 return ch.socket().getBroadcast();
223 } catch (SocketException e) {
224 throw new RuntimeIOException(e);
225 }
226 }
227
228 @Override
229 public void setBroadcast(boolean broadcast) {
230 try {
231 ch.socket().setBroadcast(broadcast);
232 } catch (SocketException e) {
233 throw new RuntimeIOException(e);
234 }
235 }
236
237 @Override
238 public int getSendBufferSize() {
239 try {
240 return ch.socket().getSendBufferSize();
241 } catch (SocketException e) {
242 throw new RuntimeIOException(e);
243 }
244 }
245
246 @Override
247 public void setSendBufferSize(int sendBufferSize) {
248 if (DatagramSessionConfigImpl.isSetSendBufferSizeAvailable()) {
249 try {
250 ch.socket().setSendBufferSize(sendBufferSize);
251 } catch (SocketException e) {
252 throw new RuntimeIOException(e);
253 }
254 }
255 }
256
257 @Override
258 public boolean isReuseAddress() {
259 try {
260 return ch.socket().getReuseAddress();
261 } catch (SocketException e) {
262 throw new RuntimeIOException(e);
263 }
264 }
265
266 @Override
267 public void setReuseAddress(boolean reuseAddress) {
268 try {
269 ch.socket().setReuseAddress(reuseAddress);
270 } catch (SocketException e) {
271 throw new RuntimeIOException(e);
272 }
273 }
274
275 @Override
276 public int getTrafficClass() {
277 if (DatagramSessionConfigImpl.isGetTrafficClassAvailable()) {
278 try {
279 return ch.socket().getTrafficClass();
280 } catch (SocketException e) {
281 throw new RuntimeIOException(e);
282 }
283 } else {
284 return 0;
285 }
286 }
287
288 @Override
289 public void setTrafficClass(int trafficClass) {
290 if (DatagramSessionConfigImpl.isSetTrafficClassAvailable()) {
291 try {
292 ch.socket().setTrafficClass(trafficClass);
293 } catch (SocketException e) {
294 throw new RuntimeIOException(e);
295 }
296 }
297 }
298 }
299 }