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.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
36
37 public class DefaultSocketChannelConfig extends DefaultChannelConfig
38 implements SocketChannelConfig {
39
40 protected final Socket javaSocket;
41 private volatile boolean allowHalfClosure;
42
43
44
45
46 public DefaultSocketChannelConfig(SocketChannel channel, Socket javaSocket) {
47 super(channel);
48 this.javaSocket = ObjectUtil.checkNotNull(javaSocket, "javaSocket");
49
50
51 if (PlatformDependent.canEnableTcpNoDelayByDefault()) {
52 try {
53 setTcpNoDelay(true);
54 } catch (Exception e) {
55
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 }