View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
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  
27  import org.apache.mina.common.BroadcastIoSession;
28  import org.apache.mina.common.IoFilterChain;
29  import org.apache.mina.common.IoHandler;
30  import org.apache.mina.common.IoService;
31  import org.apache.mina.common.IoServiceConfig;
32  import org.apache.mina.common.IoSession;
33  import org.apache.mina.common.IoSessionConfig;
34  import org.apache.mina.common.RuntimeIOException;
35  import org.apache.mina.common.TransportType;
36  import org.apache.mina.common.IoFilter.WriteRequest;
37  import org.apache.mina.common.support.BaseIoSession;
38  import org.apache.mina.transport.socket.nio.DatagramServiceConfig;
39  import org.apache.mina.transport.socket.nio.DatagramSessionConfig;
40  import org.apache.mina.util.Queue;
41  
42  /**
43   * An {@link IoSession} for datagram transport (UDP/IP).
44   * 
45   * @author The Apache Directory Project (mina-dev@directory.apache.org)
46   * @version $Rev: 584716 $, $Date: 2007-10-15 18:25:29 +0900 (월, 15 10월 2007) $
47   */
48  class DatagramSessionImpl extends BaseIoSession implements BroadcastIoSession {
49      private final IoService wrapperManager;
50  
51      private final IoServiceConfig serviceConfig;
52  
53      private final DatagramSessionConfig config = new SessionConfigImpl();
54  
55      private final DatagramService managerDelegate;
56  
57      private final DatagramFilterChain filterChain;
58  
59      private final DatagramChannel ch;
60  
61      private final Queue writeRequestQueue;
62  
63      private final IoHandler handler;
64  
65      private final SocketAddress localAddress;
66  
67      private final SocketAddress serviceAddress;
68  
69      private SocketAddress remoteAddress;
70  
71      private SelectionKey key;
72  
73      private int readBufferSize;
74  
75      /**
76       * Creates a new instance.
77       */
78      DatagramSessionImpl(IoService wrapperManager,
79              DatagramService managerDelegate, IoServiceConfig serviceConfig,
80              DatagramChannel ch, IoHandler defaultHandler,
81              SocketAddress serviceAddress, SocketAddress localAddress) {
82          this.wrapperManager = wrapperManager;
83          this.managerDelegate = managerDelegate;
84          this.filterChain = new DatagramFilterChain(this);
85          this.ch = ch;
86          this.writeRequestQueue = new Queue();
87          this.handler = defaultHandler;
88          this.remoteAddress = ch.socket().getRemoteSocketAddress();
89  
90          this.serviceAddress = serviceAddress;
91          this.localAddress = localAddress;
92          this.serviceConfig = serviceConfig;
93  
94          // Apply the initial session settings
95          IoSessionConfig sessionConfig = serviceConfig.getSessionConfig();
96          if (sessionConfig instanceof DatagramSessionConfig) {
97              DatagramSessionConfig cfg = (DatagramSessionConfig) sessionConfig;
98              this.config.setBroadcast(cfg.isBroadcast());
99              this.config.setReceiveBufferSize(cfg.getReceiveBufferSize());
100             this.config.setReuseAddress(cfg.isReuseAddress());
101             this.config.setSendBufferSize(cfg.getSendBufferSize());
102 
103             if (this.config.getTrafficClass() != cfg.getTrafficClass()) {
104                 this.config.setTrafficClass(cfg.getTrafficClass());
105             }
106         }
107     }
108 
109     public IoService getService() {
110         return wrapperManager;
111     }
112 
113     public IoServiceConfig getServiceConfig() {
114         return serviceConfig;
115     }
116 
117     public IoSessionConfig getConfig() {
118         return config;
119     }
120 
121     DatagramService getManagerDelegate() {
122         return managerDelegate;
123     }
124 
125     public IoFilterChain getFilterChain() {
126         return filterChain;
127     }
128 
129     DatagramChannel getChannel() {
130         return ch;
131     }
132 
133     SelectionKey getSelectionKey() {
134         return key;
135     }
136 
137     void setSelectionKey(SelectionKey key) {
138         this.key = key;
139     }
140 
141     public IoHandler getHandler() {
142         return handler;
143     }
144 
145     protected void close0() {
146         IoServiceConfig config = getServiceConfig();
147         if (config instanceof DatagramServiceConfig) {
148             ((DatagramServiceConfig) config).getSessionRecycler().remove(this);
149         }
150         filterChain.fireFilterClose(this);
151     }
152 
153     Queue getWriteRequestQueue() {
154         return writeRequestQueue;
155     }
156 
157     protected void write0(WriteRequest writeRequest) {
158         filterChain.fireFilterWrite(this, writeRequest);
159     }
160 
161     public TransportType getTransportType() {
162         return TransportType.DATAGRAM;
163     }
164 
165     public SocketAddress getRemoteAddress() {
166         return remoteAddress;
167     }
168 
169     void setRemoteAddress(SocketAddress remoteAddress) {
170         this.remoteAddress = remoteAddress;
171     }
172 
173     public SocketAddress getLocalAddress() {
174         return localAddress;
175     }
176 
177     public SocketAddress getServiceAddress() {
178         return serviceAddress;
179     }
180 
181     protected void updateTrafficMask() {
182         managerDelegate.updateTrafficMask(this);
183     }
184 
185     int getReadBufferSize() {
186         return readBufferSize;
187     }
188 
189     private class SessionConfigImpl extends DatagramSessionConfigImpl implements
190             DatagramSessionConfig {
191         public int getReceiveBufferSize() {
192             try {
193                 return ch.socket().getReceiveBufferSize();
194             } catch (SocketException e) {
195                 throw new RuntimeIOException(e);
196             }
197         }
198 
199         public void setReceiveBufferSize(int receiveBufferSize) {
200             if (DatagramSessionConfigImpl.isSetReceiveBufferSizeAvailable()) {
201                 try {
202                     ch.socket().setReceiveBufferSize(receiveBufferSize);
203                     // Re-retrieve the effective receive buffer size.
204                     receiveBufferSize = ch.socket().getReceiveBufferSize();
205                     DatagramSessionImpl.this.readBufferSize = receiveBufferSize;
206                 } catch (SocketException e) {
207                     throw new RuntimeIOException(e);
208                 }
209             }
210         }
211 
212         public boolean isBroadcast() {
213             try {
214                 return ch.socket().getBroadcast();
215             } catch (SocketException e) {
216                 throw new RuntimeIOException(e);
217             }
218         }
219 
220         public void setBroadcast(boolean broadcast) {
221             try {
222                 ch.socket().setBroadcast(broadcast);
223             } catch (SocketException e) {
224                 throw new RuntimeIOException(e);
225             }
226         }
227 
228         public int getSendBufferSize() {
229             try {
230                 return ch.socket().getSendBufferSize();
231             } catch (SocketException e) {
232                 throw new RuntimeIOException(e);
233             }
234         }
235 
236         public void setSendBufferSize(int sendBufferSize) {
237             if (DatagramSessionConfigImpl.isSetSendBufferSizeAvailable()) {
238                 try {
239                     ch.socket().setSendBufferSize(sendBufferSize);
240                 } catch (SocketException e) {
241                     throw new RuntimeIOException(e);
242                 }
243             }
244         }
245 
246         public boolean isReuseAddress() {
247             try {
248                 return ch.socket().getReuseAddress();
249             } catch (SocketException e) {
250                 throw new RuntimeIOException(e);
251             }
252         }
253 
254         public void setReuseAddress(boolean reuseAddress) {
255             try {
256                 ch.socket().setReuseAddress(reuseAddress);
257             } catch (SocketException e) {
258                 throw new RuntimeIOException(e);
259             }
260         }
261 
262         public int getTrafficClass() {
263             if (DatagramSessionConfigImpl.isGetTrafficClassAvailable()) {
264                 try {
265                     return ch.socket().getTrafficClass();
266                 } catch (SocketException e) {
267                     throw new RuntimeIOException(e);
268                 }
269             } else {
270                 return 0;
271             }
272         }
273 
274         public void setTrafficClass(int trafficClass) {
275             if (DatagramSessionConfigImpl.isSetTrafficClassAvailable()) {
276                 try {
277                     ch.socket().setTrafficClass(trafficClass);
278                 } catch (SocketException e) {
279                     throw new RuntimeIOException(e);
280                 }
281             }
282         }
283     }
284 }