1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
34
35 public class DefaultSocketChannelConfig extends DefaultChannelConfig
36 implements SocketChannelConfig {
37
38 protected final Socket javaSocket;
39 private volatile boolean allowHalfClosure;
40
41
42
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
52 if (PlatformDependent.canEnableTcpNoDelayByDefault()) {
53 try {
54 setTcpNoDelay(true);
55 } catch (Exception e) {
56
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 }