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    *   https://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.channel.WriteBufferWaterMark;
25  import io.netty.util.internal.ObjectUtil;
26  import io.netty.util.internal.PlatformDependent;
27  
28  import java.net.Socket;
29  import java.net.SocketException;
30  import java.util.Map;
31  
32  import static io.netty.channel.ChannelOption.*;
33  
34  /**
35   * The default {@link SocketChannelConfig} implementation.
36   */
37  public class DefaultSocketChannelConfig extends DefaultChannelConfig
38                                          implements SocketChannelConfig {
39  
40      protected final Socket javaSocket;
41      private volatile boolean allowHalfClosure;
42  
43      /**
44       * Creates a new instance.
45       */
46      public DefaultSocketChannelConfig(SocketChannel channel, Socket javaSocket) {
47          super(channel);
48          this.javaSocket = ObjectUtil.checkNotNull(javaSocket, "javaSocket");
49  
50          // Enable TCP_NODELAY by default if possible.
51          if (PlatformDependent.canEnableTcpNoDelayByDefault()) {
52              try {
53                  setTcpNoDelay(true);
54              } catch (Exception e) {
55                  // Ignore.
56              }
57          }
58      }
59  
60      @Override
61      public Map<ChannelOption<?>, Object> getOptions() {
62          return getOptions(
63                  super.getOptions(),
64                  SO_RCVBUF, SO_SNDBUF, TCP_NODELAY, SO_KEEPALIVE, SO_REUSEADDR, SO_LINGER, IP_TOS,
65                  ALLOW_HALF_CLOSURE);
66      }
67  
68      @SuppressWarnings("unchecked")
69      @Override
70      public <T> T getOption(ChannelOption<T> option) {
71          if (option == SO_RCVBUF) {
72              return (T) Integer.valueOf(getReceiveBufferSize());
73          }
74          if (option == SO_SNDBUF) {
75              return (T) Integer.valueOf(getSendBufferSize());
76          }
77          if (option == TCP_NODELAY) {
78              return (T) Boolean.valueOf(isTcpNoDelay());
79          }
80          if (option == SO_KEEPALIVE) {
81              return (T) Boolean.valueOf(isKeepAlive());
82          }
83          if (option == SO_REUSEADDR) {
84              return (T) Boolean.valueOf(isReuseAddress());
85          }
86          if (option == SO_LINGER) {
87              return (T) Integer.valueOf(getSoLinger());
88          }
89          if (option == IP_TOS) {
90              return (T) Integer.valueOf(getTrafficClass());
91          }
92          if (option == ALLOW_HALF_CLOSURE) {
93              return (T) Boolean.valueOf(isAllowHalfClosure());
94          }
95  
96          return super.getOption(option);
97      }
98  
99      @Override
100     public <T> boolean setOption(ChannelOption<T> option, T value) {
101         validate(option, value);
102 
103         if (option == SO_RCVBUF) {
104             setReceiveBufferSize((Integer) value);
105         } else if (option == SO_SNDBUF) {
106             setSendBufferSize((Integer) value);
107         } else if (option == TCP_NODELAY) {
108             setTcpNoDelay((Boolean) value);
109         } else if (option == SO_KEEPALIVE) {
110             setKeepAlive((Boolean) value);
111         } else if (option == SO_REUSEADDR) {
112             setReuseAddress((Boolean) value);
113         } else if (option == SO_LINGER) {
114             setSoLinger((Integer) value);
115         } else if (option == IP_TOS) {
116             setTrafficClass((Integer) value);
117         } else if (option == ALLOW_HALF_CLOSURE) {
118             setAllowHalfClosure((Boolean) value);
119         } else {
120             return super.setOption(option, value);
121         }
122 
123         return true;
124     }
125 
126     @Override
127     public int getReceiveBufferSize() {
128         try {
129             return javaSocket.getReceiveBufferSize();
130         } catch (SocketException e) {
131             throw new ChannelException(e);
132         }
133     }
134 
135     @Override
136     public int getSendBufferSize() {
137         try {
138             return javaSocket.getSendBufferSize();
139         } catch (SocketException e) {
140             throw new ChannelException(e);
141         }
142     }
143 
144     @Override
145     public int getSoLinger() {
146         try {
147             return javaSocket.getSoLinger();
148         } catch (SocketException e) {
149             throw new ChannelException(e);
150         }
151     }
152 
153     @Override
154     public int getTrafficClass() {
155         try {
156             return javaSocket.getTrafficClass();
157         } catch (SocketException e) {
158             throw new ChannelException(e);
159         }
160     }
161 
162     @Override
163     public boolean isKeepAlive() {
164         try {
165             return javaSocket.getKeepAlive();
166         } catch (SocketException e) {
167             throw new ChannelException(e);
168         }
169     }
170 
171     @Override
172     public boolean isReuseAddress() {
173         try {
174             return javaSocket.getReuseAddress();
175         } catch (SocketException e) {
176             throw new ChannelException(e);
177         }
178     }
179 
180     @Override
181     public boolean isTcpNoDelay() {
182         try {
183             return javaSocket.getTcpNoDelay();
184         } catch (SocketException e) {
185             throw new ChannelException(e);
186         }
187     }
188 
189     @Override
190     public SocketChannelConfig setKeepAlive(boolean keepAlive) {
191         try {
192             javaSocket.setKeepAlive(keepAlive);
193         } catch (SocketException e) {
194             throw new ChannelException(e);
195         }
196         return this;
197     }
198 
199     @Override
200     public SocketChannelConfig setPerformancePreferences(
201             int connectionTime, int latency, int bandwidth) {
202         javaSocket.setPerformancePreferences(connectionTime, latency, bandwidth);
203         return this;
204     }
205 
206     @Override
207     public SocketChannelConfig setReceiveBufferSize(int receiveBufferSize) {
208         try {
209             javaSocket.setReceiveBufferSize(receiveBufferSize);
210         } catch (SocketException e) {
211             throw new ChannelException(e);
212         }
213         return this;
214     }
215 
216     @Override
217     public SocketChannelConfig setReuseAddress(boolean reuseAddress) {
218         try {
219             javaSocket.setReuseAddress(reuseAddress);
220         } catch (SocketException e) {
221             throw new ChannelException(e);
222         }
223         return this;
224     }
225 
226     @Override
227     public SocketChannelConfig setSendBufferSize(int sendBufferSize) {
228         try {
229             javaSocket.setSendBufferSize(sendBufferSize);
230         } catch (SocketException e) {
231             throw new ChannelException(e);
232         }
233         return this;
234     }
235 
236     @Override
237     public SocketChannelConfig setSoLinger(int soLinger) {
238         try {
239             if (soLinger < 0) {
240                 javaSocket.setSoLinger(false, 0);
241             } else {
242                 javaSocket.setSoLinger(true, soLinger);
243             }
244         } catch (SocketException e) {
245             throw new ChannelException(e);
246         }
247         return this;
248     }
249 
250     @Override
251     public SocketChannelConfig setTcpNoDelay(boolean tcpNoDelay) {
252         try {
253             javaSocket.setTcpNoDelay(tcpNoDelay);
254         } catch (SocketException e) {
255             throw new ChannelException(e);
256         }
257         return this;
258     }
259 
260     @Override
261     public SocketChannelConfig setTrafficClass(int trafficClass) {
262         try {
263             javaSocket.setTrafficClass(trafficClass);
264         } catch (SocketException e) {
265             throw new ChannelException(e);
266         }
267         return this;
268     }
269 
270     @Override
271     public boolean isAllowHalfClosure() {
272         return allowHalfClosure;
273     }
274 
275     @Override
276     public SocketChannelConfig setAllowHalfClosure(boolean allowHalfClosure) {
277         this.allowHalfClosure = allowHalfClosure;
278         return this;
279     }
280 
281     @Override
282     public SocketChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis) {
283         super.setConnectTimeoutMillis(connectTimeoutMillis);
284         return this;
285     }
286 
287     @Override
288     @Deprecated
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 setWriteBufferWaterMark(WriteBufferWaterMark writeBufferWaterMark) {
338         super.setWriteBufferWaterMark(writeBufferWaterMark);
339         return this;
340     }
341 
342     @Override
343     public SocketChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator) {
344         super.setMessageSizeEstimator(estimator);
345         return this;
346     }
347 }