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;
21  
22  import java.net.InetSocketAddress;
23  import java.net.Socket;
24  import java.net.SocketException;
25  import java.nio.channels.SelectionKey;
26  import java.nio.channels.SocketChannel;
27  
28  import org.apache.mina.core.RuntimeIoException;
29  import org.apache.mina.core.buffer.IoBuffer;
30  import org.apache.mina.core.file.FileRegion;
31  import org.apache.mina.core.filterchain.DefaultIoFilterChain;
32  import org.apache.mina.core.filterchain.IoFilterChain;
33  import org.apache.mina.core.service.DefaultTransportMetadata;
34  import org.apache.mina.core.service.IoHandler;
35  import org.apache.mina.core.service.IoProcessor;
36  import org.apache.mina.core.service.IoService;
37  import org.apache.mina.core.service.TransportMetadata;
38  import org.apache.mina.core.session.IoSession;
39  import org.apache.mina.transport.socket.AbstractSocketSessionConfig;
40  import org.apache.mina.transport.socket.SocketSessionConfig;
41  
42  /**
43   * An {@link IoSession} for socket transport (TCP/IP).
44   *
45   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
46   */
47  class NioSocketSession extends NioSession {
48  
49      static final TransportMetadata METADATA =
50              new DefaultTransportMetadata(
51                      "nio", "socket", false, true,
52                      InetSocketAddress.class,
53                      SocketSessionConfig.class,
54                      IoBuffer.class, FileRegion.class);
55  
56      private final IoService service;
57  
58      private final SocketSessionConfig config = new SessionConfigImpl();
59  
60      private final IoFilterChain filterChain = new DefaultIoFilterChain(this);
61  
62      private final SocketChannel ch;
63  
64      private final IoHandler handler;
65  
66      private SelectionKey key;
67  
68      
69      /**
70       * 
71       * Creates a new instance of NioSocketSession.
72       *
73       * @param service the associated IoService 
74       * @param processor the associated IoProcessor
75       * @param ch the used channel
76       */
77      public NioSocketSession(IoService service, IoProcessor<NioSession> processor, SocketChannel ch) {
78          super(processor);
79          this.service = service;
80          this.ch = ch;
81          this.handler = service.getHandler();
82          this.config.setAll(service.getSessionConfig());
83      }
84  
85      public IoService getService() {
86          return service;
87      }
88  
89      public SocketSessionConfig getConfig() {
90          return config;
91      }
92  
93      public IoFilterChain getFilterChain() {
94          return filterChain;
95      }
96  
97      public TransportMetadata getTransportMetadata() {
98          return METADATA;
99      }
100 
101     @Override
102     SocketChannel getChannel() {
103         return ch;
104     }
105 
106     @Override
107     SelectionKey getSelectionKey() {
108         return key;
109     }
110 
111     @Override
112     void setSelectionKey(SelectionKey key) {
113         this.key = key;
114     }
115 
116     public IoHandler getHandler() {
117         return handler;
118     }
119 
120     /**
121      * {@inheritDoc}
122      */
123     public InetSocketAddress getRemoteAddress() {
124         if ( ch == null ) {
125             return null;
126         }
127         
128         Socket socket = ch.socket();
129         
130         if ( socket == null ) {
131             return null;
132         }
133         
134         return (InetSocketAddress) socket.getRemoteSocketAddress();
135     }
136 
137     /**
138      * {@inheritDoc}
139      */
140     public InetSocketAddress getLocalAddress() {
141         if ( ch == null ) {
142             return null;
143         }
144         
145         Socket socket = ch.socket();
146         
147         if ( socket == null ) {
148             return null;
149         }
150         
151         return (InetSocketAddress) socket.getLocalSocketAddress();
152     }
153 
154     @Override
155     public InetSocketAddress getServiceAddress() {
156         return (InetSocketAddress) super.getServiceAddress();
157     }
158 
159     private class SessionConfigImpl extends AbstractSocketSessionConfig {
160         public boolean isKeepAlive() {
161             try {
162                 return ch.socket().getKeepAlive();
163             } catch (SocketException e) {
164                 throw new RuntimeIoException(e);
165             }
166         }
167 
168         public void setKeepAlive(boolean on) {
169             try {
170                 ch.socket().setKeepAlive(on);
171             } catch (SocketException e) {
172                 throw new RuntimeIoException(e);
173             }
174         }
175 
176         public boolean isOobInline() {
177             try {
178                 return ch.socket().getOOBInline();
179             } catch (SocketException e) {
180                 throw new RuntimeIoException(e);
181             }
182         }
183 
184         public void setOobInline(boolean on) {
185             try {
186                 ch.socket().setOOBInline(on);
187             } catch (SocketException e) {
188                 throw new RuntimeIoException(e);
189             }
190         }
191 
192         public boolean isReuseAddress() {
193             try {
194                 return ch.socket().getReuseAddress();
195             } catch (SocketException e) {
196                 throw new RuntimeIoException(e);
197             }
198         }
199 
200         public void setReuseAddress(boolean on) {
201             try {
202                 ch.socket().setReuseAddress(on);
203             } catch (SocketException e) {
204                 throw new RuntimeIoException(e);
205             }
206         }
207 
208         public int getSoLinger() {
209             try {
210                 return ch.socket().getSoLinger();
211             } catch (SocketException e) {
212                 throw new RuntimeIoException(e);
213             }
214         }
215 
216         public void setSoLinger(int linger) {
217             try {
218                 if (linger < 0) {
219                     ch.socket().setSoLinger(false, 0);
220                 } else {
221                     ch.socket().setSoLinger(true, linger);
222                 }
223             } catch (SocketException e) {
224                 throw new RuntimeIoException(e);
225             }
226         }
227 
228         public boolean isTcpNoDelay() {
229             if (!isConnected()) {
230                 return false;
231             }
232 
233             try {
234                 return ch.socket().getTcpNoDelay();
235             } catch (SocketException e) {
236                 throw new RuntimeIoException(e);
237             }
238         }
239 
240         public void setTcpNoDelay(boolean on) {
241             try {
242                 ch.socket().setTcpNoDelay(on);
243             } catch (SocketException e) {
244                 throw new RuntimeIoException(e);
245             }
246         }
247 
248         /**
249          * {@inheritDoc}
250          */
251         public int getTrafficClass() {
252             try {
253                 return ch.socket().getTrafficClass();
254             } catch (SocketException e) {
255                 throw new RuntimeIoException(e);
256             }
257         }
258 
259         /**
260          * {@inheritDoc}
261          */
262         public void setTrafficClass(int tc) {
263             try {
264                 ch.socket().setTrafficClass(tc);
265             } catch (SocketException e) {
266                 throw new RuntimeIoException(e);
267             }
268         }
269 
270         public int getSendBufferSize() {
271             try {
272                 return ch.socket().getSendBufferSize();
273             } catch (SocketException e) {
274                 throw new RuntimeIoException(e);
275             }
276         }
277 
278         public void setSendBufferSize(int size) {
279             try {
280                 ch.socket().setSendBufferSize(size);
281             } catch (SocketException e) {
282                 throw new RuntimeIoException(e);
283             }
284         }
285 
286         public int getReceiveBufferSize() {
287             try {
288                 return ch.socket().getReceiveBufferSize();
289             } catch (SocketException e) {
290                 throw new RuntimeIoException(e);
291             }
292         }
293 
294         public void setReceiveBufferSize(int size) {
295             try {
296                 ch.socket().setReceiveBufferSize(size);
297             } catch (SocketException e) {
298                 throw new RuntimeIoException(e);
299             }
300         }
301     }
302 }