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