/* * Copyright (C) 2015 SoftIndex LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package io.datakernel.net; import io.datakernel.util.MemSize; import java.io.IOException; import java.nio.channels.SocketChannel; import static io.datakernel.util.Preconditions.check; import static java.net.StandardSocketOptions.*; /** * This class used to change settings for socket. It will be applying with creating new socket */ public final class SocketSettings { protected static final int DEF_INT = -1; protected static final byte DEF_BOOL = -1; protected static final byte TRUE = 1; protected static final byte FALSE = 0; private final int sendBufferSize; private final int receiveBufferSize; private final byte keepAlive; private final byte reuseAddress; private final byte tcpNoDelay; private final long implReadTimeout; private final long implWriteTimeout; private final int implReadSize; private final int implWriteSize; // region builders private SocketSettings(int sendBufferSize, int receiveBufferSize, byte keepAlive, byte reuseAddress, byte tcpNoDelay, long implReadTimeout, long implWriteTimeout, int implReadSize, int implWriteSize) { this.sendBufferSize = sendBufferSize; this.receiveBufferSize = receiveBufferSize; this.keepAlive = keepAlive; this.reuseAddress = reuseAddress; this.tcpNoDelay = tcpNoDelay; this.implReadTimeout = implReadTimeout; this.implWriteTimeout = implWriteTimeout; this.implReadSize = implReadSize; this.implWriteSize = implWriteSize; } public static SocketSettings create() { return new SocketSettings(DEF_INT, DEF_INT, DEF_BOOL, DEF_BOOL, DEF_BOOL, DEF_INT, DEF_INT, DEF_INT, DEF_INT); } public SocketSettings withSendBufferSize(int sendBufferSize) { return new SocketSettings(sendBufferSize, receiveBufferSize, keepAlive, reuseAddress, tcpNoDelay, implReadTimeout, implWriteTimeout, implReadSize, implWriteSize); } public SocketSettings withSendBufferSize(MemSize sendBufferSize) { return withSendBufferSize((int) sendBufferSize.get()); } public SocketSettings withReceiveBufferSize(int receiveBufferSize) { return new SocketSettings(sendBufferSize, receiveBufferSize, keepAlive, reuseAddress, tcpNoDelay, implReadTimeout, implWriteTimeout, implReadSize, implWriteSize); } public SocketSettings withReceiveBufferSize(MemSize receiveBufferSize) { return withReceiveBufferSize((int) receiveBufferSize.get()); } public SocketSettings withKeepAlive(boolean keepAlive) { return new SocketSettings(sendBufferSize, receiveBufferSize, keepAlive ? TRUE : FALSE, reuseAddress, tcpNoDelay, implReadTimeout, implWriteTimeout, implReadSize, implWriteSize); } public SocketSettings withReuseAddress(boolean reuseAddress) { return new SocketSettings(sendBufferSize, receiveBufferSize, keepAlive, reuseAddress ? TRUE : FALSE, tcpNoDelay, implReadTimeout, implWriteTimeout, implReadSize, implWriteSize); } public SocketSettings withTcpNoDelay(boolean tcpNoDelay) { return new SocketSettings(sendBufferSize, receiveBufferSize, keepAlive, reuseAddress, tcpNoDelay ? TRUE : FALSE, implReadTimeout, implWriteTimeout, implReadSize, implWriteSize); } public SocketSettings withImplReadTimeout(long implReadTimeout) { return new SocketSettings(sendBufferSize, receiveBufferSize, keepAlive, reuseAddress, tcpNoDelay, implReadTimeout, implWriteTimeout, implReadSize, implWriteSize); } public SocketSettings withImplWriteTimeout(long implWriteTimeout) { return new SocketSettings(sendBufferSize, receiveBufferSize, keepAlive, reuseAddress, tcpNoDelay, implReadTimeout, implWriteTimeout, implReadSize, implWriteSize); } public SocketSettings withImplReadSize(int implReadSize) { return new SocketSettings(sendBufferSize, receiveBufferSize, keepAlive, reuseAddress, tcpNoDelay, implReadTimeout, implWriteTimeout, implReadSize, implWriteSize); } public SocketSettings withImplReadSize(MemSize implReadSize) { return withImplReadSize((int) implReadSize.get()); } public SocketSettings withImplWriteSize(int implWriteSize) { return new SocketSettings(sendBufferSize, receiveBufferSize, keepAlive, reuseAddress, tcpNoDelay, implReadTimeout, implWriteTimeout, implReadSize, implWriteSize); } public SocketSettings withImplWriteSize(MemSize implWriteSize) { return withImplWriteSize((int) implWriteSize.get()); } // endregion public void applySettings(SocketChannel channel) throws IOException { if (sendBufferSize != DEF_INT) { channel.setOption(SO_SNDBUF, sendBufferSize); } if (receiveBufferSize != DEF_INT) { channel.setOption(SO_RCVBUF, receiveBufferSize); } if (keepAlive != DEF_BOOL) { channel.setOption(SO_KEEPALIVE, keepAlive != FALSE); } if (reuseAddress != DEF_BOOL) { channel.setOption(SO_REUSEADDR, reuseAddress != FALSE); } if (tcpNoDelay != DEF_BOOL) { channel.setOption(TCP_NODELAY, tcpNoDelay != FALSE); } } public boolean hasSendBufferSize() { return sendBufferSize != DEF_INT; } public int getSendBufferSize() { check(hasSendBufferSize()); return sendBufferSize; } public boolean hasReceiveBufferSize() { return receiveBufferSize != DEF_INT; } public int getReceiveBufferSize() { check(hasReceiveBufferSize()); return receiveBufferSize; } public boolean hasKeepAlive() { return keepAlive != DEF_BOOL; } public boolean getKeepAlive() { check(hasKeepAlive()); return keepAlive != FALSE; } public boolean hasReuseAddress() { return reuseAddress != DEF_BOOL; } public boolean getReuseAddress() { check(hasReuseAddress()); return reuseAddress != FALSE; } public boolean hasTcpNoDelay() { return tcpNoDelay != DEF_BOOL; } public boolean getTcpNoDelay() { check(hasTcpNoDelay()); return tcpNoDelay != FALSE; } public boolean hasImplReadTimeout() { return implReadTimeout != DEF_INT; } public long getImplReadTimeout() { assert hasImplReadTimeout(); return implReadTimeout; } public boolean hasImplWriteTimeout() { return implWriteTimeout != DEF_INT; } public long getImplWriteTimeout() { assert hasImplWriteTimeout(); return implWriteTimeout; } public boolean hasImplReadSize() { return implReadSize != DEF_INT; } public int getImplReadSize() { assert hasImplReadSize(); return implReadSize; } public boolean hasImplWriteSize() { return implWriteSize != DEF_INT; } public int getImplWriteSize() { assert hasImplWriteSize(); return implWriteSize; } }