View Javadoc
1   /*
2    * Copyright 2012 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.channel.socket;
17  
18  import io.netty.buffer.ByteBufAllocator;
19  import io.netty.channel.ChannelException;
20  import io.netty.channel.ChannelOption;
21  import io.netty.channel.DefaultChannelConfig;
22  import io.netty.channel.MessageSizeEstimator;
23  import io.netty.channel.RecvByteBufAllocator;
24  import io.netty.util.internal.PlatformDependent;
25  
26  import java.net.Socket;
27  import java.net.SocketException;
28  import java.util.Map;
29  
30  import static io.netty.channel.ChannelOption.*;
31  
32  /**
33   * The default {@link SocketChannelConfig} implementation.
34   */
35  public class DefaultSocketChannelConfig extends DefaultChannelConfig
36                                          implements SocketChannelConfig {
37  
38      protected final Socket javaSocket;
39      private volatile boolean allowHalfClosure;
40  
41      /**
42       * Creates a new instance.
43       */
44      public DefaultSocketChannelConfig(SocketChannel channel, Socket javaSocket) {
45          super(channel);
46          if (javaSocket == null) {
47              throw new NullPointerException("javaSocket");
48          }
49          this.javaSocket = javaSocket;
50  
51          // Enable TCP_NODELAY by default if possible.
52          if (PlatformDependent.canEnableTcpNoDelayByDefault()) {
53              try {
54                  setTcpNoDelay(true);
55              } catch (Exception e) {
56                  // Ignore.
57              }
58          }
59      }
60  
61      @Override
62      public Map<ChannelOption<?>, Object> getOptions() {
63          return getOptions(
64                  super.getOptions(),
65                  SO_RCVBUF, SO_SNDBUF, TCP_NODELAY, SO_KEEPALIVE, SO_REUSEADDR, SO_LINGER, IP_TOS,
66                  ALLOW_HALF_CLOSURE);
67      }
68  
69      @SuppressWarnings("unchecked")
70      @Override
71      public <T> T getOption(ChannelOption<T> option) {
72          if (option == SO_RCVBUF) {
73              return (T) Integer.valueOf(getReceiveBufferSize());
74          }
75          if (option == SO_SNDBUF) {
76              return (T) Integer.valueOf(getSendBufferSize());
77          }
78          if (option == TCP_NODELAY) {
79              return (T) Boolean.valueOf(isTcpNoDelay());
80          }
81          if (option == SO_KEEPALIVE) {
82              return (T) Boolean.valueOf(isKeepAlive());
83          }
84          if (option == SO_REUSEADDR) {
85              return (T) Boolean.valueOf(isReuseAddress());
86          }
87          if (option == SO_LINGER) {
88              return (T) Integer.valueOf(getSoLinger());
89          }
90          if (option == IP_TOS) {
91              return (T) Integer.valueOf(getTrafficClass());
92          }
93          if (option == ALLOW_HALF_CLOSURE) {
94              return (T) Boolean.valueOf(isAllowHalfClosure());
95          }
96  
97          return super.getOption(option);
98      }
99  
100     @Override
101     public <T> boolean setOption(ChannelOption<T> option, T value) {
102         validate(option, value);
103 
104         if (option == SO_RCVBUF) {
105             setReceiveBufferSize((Integer) value);
106         } else if (option == SO_SNDBUF) {
107             setSendBufferSize((Integer) value);
108         } else if (option == TCP_NODELAY) {
109             setTcpNoDelay((Boolean) value);
110         } else if (option == SO_KEEPALIVE) {
111             setKeepAlive((Boolean) value);
112         } else if (option == SO_REUSEADDR) {
113             setReuseAddress((Boolean) value);
114         } else if (option == SO_LINGER) {
115             setSoLinger((Integer) value);
116         } else if (option == IP_TOS) {
117             setTrafficClass((Integer) value);
118         } else if (option == ALLOW_HALF_CLOSURE) {
119             setAllowHalfClosure((Boolean) value);
120         } else {
121             return super.setOption(option, value);
122         }
123 
124         return true;
125     }
126 
127     @Override
128     public int getReceiveBufferSize() {
129         try {
130             return javaSocket.getReceiveBufferSize();
131         } catch (SocketException e) {
132             throw new ChannelException(e);
133         }
134     }
135 
136     @Override
137     public int getSendBufferSize() {
138         try {
139             return javaSocket.getSendBufferSize();
140         } catch (SocketException e) {
141             throw new ChannelException(e);
142         }
143     }
144 
145     @Override
146     public int getSoLinger() {
147         try {
148             return javaSocket.getSoLinger();
149         } catch (SocketException e) {
150             throw new ChannelException(e);
151         }
152     }
153 
154     @Override
155     public int getTrafficClass() {
156         try {
157             return javaSocket.getTrafficClass();
158         } catch (SocketException e) {
159             throw new ChannelException(e);
160         }
161     }
162 
163     @Override
164     public boolean isKeepAlive() {
165         try {
166             return javaSocket.getKeepAlive();
167         } catch (SocketException e) {
168             throw new ChannelException(e);
169         }
170     }
171 
172     @Override
173     public boolean isReuseAddress() {
174         try {
175             return javaSocket.getReuseAddress();
176         } catch (SocketException e) {
177             throw new ChannelException(e);
178         }
179     }
180 
181     @Override
182     public boolean isTcpNoDelay() {
183         try {
184             return javaSocket.getTcpNoDelay();
185         } catch (SocketException e) {
186             throw new ChannelException(e);
187         }
188     }
189 
190     @Override
191     public SocketChannelConfig setKeepAlive(boolean keepAlive) {
192         try {
193             javaSocket.setKeepAlive(keepAlive);
194         } catch (SocketException e) {
195             throw new ChannelException(e);
196         }
197         return this;
198     }
199 
200     @Override
201     public SocketChannelConfig setPerformancePreferences(
202             int connectionTime, int latency, int bandwidth) {
203         javaSocket.setPerformancePreferences(connectionTime, latency, bandwidth);
204         return this;
205     }
206 
207     @Override
208     public SocketChannelConfig setReceiveBufferSize(int receiveBufferSize) {
209         try {
210             javaSocket.setReceiveBufferSize(receiveBufferSize);
211         } catch (SocketException e) {
212             throw new ChannelException(e);
213         }
214         return this;
215     }
216 
217     @Override
218     public SocketChannelConfig setReuseAddress(boolean reuseAddress) {
219         try {
220             javaSocket.setReuseAddress(reuseAddress);
221         } catch (SocketException e) {
222             throw new ChannelException(e);
223         }
224         return this;
225     }
226 
227     @Override
228     public SocketChannelConfig setSendBufferSize(int sendBufferSize) {
229         try {
230             javaSocket.setSendBufferSize(sendBufferSize);
231         } catch (SocketException e) {
232             throw new ChannelException(e);
233         }
234         return this;
235     }
236 
237     @Override
238     public SocketChannelConfig setSoLinger(int soLinger) {
239         try {
240             if (soLinger < 0) {
241                 javaSocket.setSoLinger(false, 0);
242             } else {
243                 javaSocket.setSoLinger(true, soLinger);
244             }
245         } catch (SocketException e) {
246             throw new ChannelException(e);
247         }
248         return this;
249     }
250 
251     @Override
252     public SocketChannelConfig setTcpNoDelay(boolean tcpNoDelay) {
253         try {
254             javaSocket.setTcpNoDelay(tcpNoDelay);
255         } catch (SocketException e) {
256             throw new ChannelException(e);
257         }
258         return this;
259     }
260 
261     @Override
262     public SocketChannelConfig setTrafficClass(int trafficClass) {
263         try {
264             javaSocket.setTrafficClass(trafficClass);
265         } catch (SocketException e) {
266             throw new ChannelException(e);
267         }
268         return this;
269     }
270 
271     @Override
272     public boolean isAllowHalfClosure() {
273         return allowHalfClosure;
274     }
275 
276     @Override
277     public SocketChannelConfig setAllowHalfClosure(boolean allowHalfClosure) {
278         this.allowHalfClosure = allowHalfClosure;
279         return this;
280     }
281 
282     @Override
283     public SocketChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis) {
284         super.setConnectTimeoutMillis(connectTimeoutMillis);
285         return this;
286     }
287 
288     @Override
289     public SocketChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead) {
290         super.setMaxMessagesPerRead(maxMessagesPerRead);
291         return this;
292     }
293 
294     @Override
295     public SocketChannelConfig setWriteSpinCount(int writeSpinCount) {
296         super.setWriteSpinCount(writeSpinCount);
297         return this;
298     }
299 
300     @Override
301     public SocketChannelConfig setAllocator(ByteBufAllocator allocator) {
302         super.setAllocator(allocator);
303         return this;
304     }
305 
306     @Override
307     public SocketChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator) {
308         super.setRecvByteBufAllocator(allocator);
309         return this;
310     }
311 
312     @Override
313     public SocketChannelConfig setAutoRead(boolean autoRead) {
314          super.setAutoRead(autoRead);
315         return this;
316     }
317 
318     @Override
319     public SocketChannelConfig setAutoClose(boolean autoClose) {
320         super.setAutoClose(autoClose);
321         return this;
322     }
323 
324     @Override
325     public SocketChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark) {
326         super.setWriteBufferHighWaterMark(writeBufferHighWaterMark);
327         return this;
328     }
329 
330     @Override
331     public SocketChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark) {
332         super.setWriteBufferLowWaterMark(writeBufferLowWaterMark);
333         return this;
334     }
335 
336     @Override
337     public SocketChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator) {
338         super.setMessageSizeEstimator(estimator);
339         return this;
340     }
341 }