1. package org.rx.socks;
  2.  
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.rx.core.LogWriter;
  5. import org.rx.core.NQuery;
  6. import org.rx.beans.DateTime;
  7.  
  8. import java.io.IOException;
  9. import java.net.InetSocketAddress;
  10. import java.net.Socket;
  11.  
  12. import java.util.Map;
  13. import java.util.Timer;
  14. import java.util.TimerTask;
  15. import java.util.concurrent.ConcurrentHashMap;
  16. import java.util.concurrent.ConcurrentLinkedDeque;
  17.  
  18. import static org.rx.core.Contract.require;
  19.  
  20. @Slf4j
  21. public final class SocketPool extends Traceable implements AutoCloseable {
  22. public static final class PooledSocket implements AutoCloseable {
  23. private final SocketPool owner;
  24. private DateTime lastActive;
  25. public final Socket socket;
  26.  
  27. public boolean isConnected() {
  28. return !owner.isClosed() && !socket.isClosed() && socket.isConnected();
  29. }
  30.  
  31. public DateTime getLastActive() {
  32. return lastActive;
  33. }
  34.  
  35. public void setLastActive(DateTime lastActive) {
  36. this.lastActive = lastActive;
  37. }
  38.  
  39. private PooledSocket(SocketPool owner, Socket socket) {
  40. this.owner = owner;
  41. this.socket = socket;
  42. lastActive = DateTime.utcNow();
  43. }
  44.  
  45. @Override
  46. public void close() {
  47. owner.returnSocket(this);
  48. }
  49. }
  50.  
  51. public static final SocketPool Pool = new SocketPool();
  52. private static final int DefaultConnectTimeout = 30000;
  53. private static final int DefaultMaxIdleMillis = 120000;
  54. private static final int DefaultMaxSocketsCount = 64;
  55. private final ConcurrentHashMap<InetSocketAddress, ConcurrentLinkedDeque<PooledSocket>> pool;
  56. private volatile int connectTimeout;
  57. private volatile int maxIdleMillis;
  58. private volatile int maxSocketsCount;
  59. private final Timer timer;
  60. private volatile boolean isTimerRun;
  61.  
  62. public int getConnectTimeout() {
  63. return connectTimeout;
  64. }
  65.  
  66. public void setConnectTimeout(int connectTimeout) {
  67. this.connectTimeout = connectTimeout;
  68. }
  69.  
  70. public int getMaxIdleMillis() {
  71. return maxIdleMillis;
  72. }
  73.  
  74. public void setMaxIdleMillis(int maxIdleMillis) {
  75. if (maxIdleMillis <= 0) {
  76. maxIdleMillis = DefaultMaxIdleMillis;
  77. }
  78. this.maxIdleMillis = maxIdleMillis;
  79. }
  80.  
  81. public int getMaxSocketsCount() {
  82. return maxSocketsCount;
  83. }
  84.  
  85. public void setMaxSocketsCount(int maxSocketsCount) {
  86. if (maxSocketsCount < 0) {
  87. maxSocketsCount = 0;
  88. }
  89. this.maxSocketsCount = maxSocketsCount;
  90. }
  91.  
  92. private SocketPool() {
  93. pool = new ConcurrentHashMap<>();
  94. connectTimeout = DefaultConnectTimeout;
  95. maxIdleMillis = DefaultMaxIdleMillis;
  96. maxSocketsCount = DefaultMaxSocketsCount;
  97. String n = "SocketPool";
  98. timer = new Timer(n, true);
  99. LogWriter tracer = new LogWriter();
  100. tracer.setPrefix(n + " ");
  101. tracer.info("started..");
  102. setTracer(tracer);
  103. }
  104.  
  105. @Override
  106. protected void freeObjects() {
  107. clear();
  108. }
  109.  
  110. private void runTimer() {
  111. if (isTimerRun) {
  112. return;
  113. }
  114. synchronized (timer) {
  115. if (isTimerRun) {
  116. return;
  117. }
  118.  
  119. long period = 90000;
  120. timer.schedule(new TimerTask() {
  121. @Override
  122. public void run() {
  123. clearIdleSockets();
  124. }
  125. }, period, period);
  126. isTimerRun = true;
  127. }
  128. getTracer().info("runTimer..");
  129. }
  130.  
  131. private void clearIdleSockets() {
  132. for (Map.Entry<InetSocketAddress, ConcurrentLinkedDeque<PooledSocket>> entry : NQuery.of(pool.entrySet())) {
  133. ConcurrentLinkedDeque<PooledSocket> sockets = entry.getValue();
  134. if (sockets == null) {
  135. continue;
  136. }
  137.  
  138. for (PooledSocket socket : NQuery.of(sockets)) {
  139. if (!socket.isConnected()
  140. || DateTime.utcNow().subtract(socket.getLastActive()).getTotalMilliseconds() >= maxIdleMillis) {
  141. sockets.remove(socket);
  142. getTracer().info("clear idle socket[local=%s, remote=%s]..",
  143. Sockets.getId(socket.socket, false), Sockets.getId(socket.socket, true));
  144. }
  145. }
  146. if (sockets.isEmpty()) {
  147. pool.remove(entry.getKey());
  148. }
  149. }
  150. if (pool.size() == 0) {
  151. stopTimer();
  152. }
  153. }
  154.  
  155. private void stopTimer() {
  156. synchronized (timer) {
  157. timer.cancel();
  158. timer.purge();
  159. isTimerRun = false;
  160. }
  161. getTracer().info("stopTimer..");
  162. }
  163.  
  164. private ConcurrentLinkedDeque<PooledSocket> getSockets(InetSocketAddress remoteAddr) {
  165. ConcurrentLinkedDeque<PooledSocket> sockets = pool.get(remoteAddr);
  166. if (sockets == null) {
  167. pool.put(remoteAddr, sockets = new ConcurrentLinkedDeque<>());
  168. runTimer();
  169. }
  170. return sockets;
  171. }
  172.  
  173. public PooledSocket borrowSocket(InetSocketAddress remoteAddr) {
  174. checkNotClosed();
  175. require(remoteAddr);
  176.  
  177. boolean isExisted = true;
  178. ConcurrentLinkedDeque<PooledSocket> sockets = getSockets(remoteAddr);
  179. PooledSocket pooledSocket;
  180. if ((pooledSocket = sockets.pollFirst()) == null) {
  181. Socket sock = new Socket();
  182. try {
  183. sock.connect(remoteAddr, connectTimeout);
  184. } catch (IOException ex) {
  185. throw new SocketException(remoteAddr, ex);
  186. }
  187. pooledSocket = new PooledSocket(this, sock);
  188. isExisted = false;
  189. }
  190. if (!pooledSocket.isConnected()) {
  191. if (isExisted) {
  192. sockets.remove(pooledSocket);
  193. }
  194. return borrowSocket(remoteAddr);
  195. }
  196. Socket sock = pooledSocket.socket;
  197. getTracer().info("borrow %s socket[local=%s, remote=%s]..", isExisted ? "existed" : "new",
  198. Sockets.getId(sock, false), Sockets.getId(sock, true));
  199. return pooledSocket;
  200. }
  201.  
  202. public void returnSocket(PooledSocket pooledSocket) {
  203. checkNotClosed();
  204. require(pooledSocket);
  205.  
  206. String action = "return";
  207. try {
  208. if (!pooledSocket.isConnected()) {
  209. action = "discard closed";
  210. return;
  211. }
  212. pooledSocket.setLastActive(DateTime.utcNow());
  213. ConcurrentLinkedDeque<PooledSocket> sockets = getSockets(
  214. (InetSocketAddress) pooledSocket.socket.getRemoteSocketAddress());
  215. if (sockets.size() >= maxSocketsCount || sockets.contains(pooledSocket)) {
  216. action = "discard contains";
  217. return;
  218. }
  219.  
  220. sockets.addFirst(pooledSocket);
  221. } finally {
  222. Socket sock = pooledSocket.socket;
  223. getTracer().info("%s socket[local=%s, remote=%s]..", action, Sockets.getId(sock, false),
  224. Sockets.getId(sock, true));
  225. }
  226. }
  227.  
  228. public void clear() {
  229. checkNotClosed();
  230.  
  231. for (Socket socket : NQuery.of(pool.values()).selectMany(p -> p).select(p -> p.socket)) {
  232. try {
  233. getTracer().info("clear socket[local=%s, remote=%s]..", Sockets.getId(socket, false),
  234. Sockets.getId(socket, true));
  235. Sockets.close(socket);
  236. } catch (Exception ex) {
  237. log.error("SocketPool clear", ex);
  238. }
  239. }
  240. pool.clear();
  241. }
  242. }
  1. package org.rx.socks;
  2.  
  3. import org.rx.core.Disposable;
  4. import org.rx.core.LogWriter;
  5.  
  6. import static org.rx.core.Contract.isNull;
  7.  
  8. public abstract class Traceable extends Disposable {
  9. private LogWriter tracer;
  10.  
  11. public LogWriter getTracer() {
  12. return tracer;
  13. }
  14.  
  15. public synchronized void setTracer(LogWriter tracer) {
  16. this.tracer = isNull(tracer, new LogWriter());
  17. }
  18. }
  1. package org.rx.socks;
  2.  
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.rx.beans.$;
  5. import org.rx.beans.Tuple;
  6. import org.rx.util.BufferSegment;
  7. import org.rx.util.BytesSegment;
  8. import org.rx.core.*;
  9. import org.rx.core.AsyncTask;
  10. import org.rx.io.MemoryStream;
  11.  
  12. import java.io.IOException;
  13. import java.net.*;
  14. import java.util.ArrayList;
  15. import java.util.Collections;
  16. import java.util.List;
  17.  
  18. import static org.rx.beans.$.$;
  19. import static org.rx.core.Contract.isNull;
  20. import static org.rx.core.Contract.require;
  21.  
  22. @Slf4j
  23. public class DirectSocket extends Traceable implements AutoCloseable {
  24. @FunctionalInterface
  25. public interface SocketSupplier {
  26. Tuple<AutoCloseable, Socket> get(MemoryStream pack);
  27. }
  28.  
  29. private static class ClientItem {
  30. private final DirectSocket owner;
  31. private final BufferSegment segment;
  32. public final NetworkStream stream;
  33. public final AutoCloseable toSock;
  34. public final NetworkStream toStream;
  35.  
  36. public ClientItem(Socket client, DirectSocket owner) {
  37. this.owner = owner;
  38. segment = new BufferSegment(Contract.config.getDefaultBufferSize(), 2);
  39. try {
  40. stream = new NetworkStream(client, segment.alloc());
  41. if (owner.directAddress != null) {
  42. SocketPool.PooledSocket pooledSocket = App.retry(owner.connectRetryCount,
  43. p -> SocketPool.Pool.borrowSocket(p.directAddress), owner);
  44. toSock = pooledSocket;
  45. toStream = new NetworkStream(pooledSocket.socket, segment.alloc(), false);
  46. return;
  47. }
  48. if (owner.directSupplier != null) {
  49. MemoryStream firstPack = new MemoryStream(32, true);
  50. BytesSegment buffer = stream.getSegment();
  51. int read;
  52. while ((read = stream.readSegment()) > 0) {
  53. System.out.println("----:" + Bytes.toString(buffer.array, buffer.offset, read));
  54. firstPack.write(buffer.array, buffer.offset, read);
  55. Tuple<AutoCloseable, Socket> toSocks;
  56. if ((toSocks = owner.directSupplier.get(firstPack)) != null) {
  57. toSock = toSocks.left;
  58. firstPack.writeTo(toStream = new NetworkStream(toSocks.right, segment.alloc(), false));
  59. return;
  60. }
  61. }
  62. log.info("DirectSocket ClientState directSupplier read: {}\ncontent: {}", read,
  63. Bytes.toString(firstPack.toArray(), 0, firstPack.getLength()));
  64. }
  65. } catch (IOException ex) {
  66. throw new SocketException((InetSocketAddress) client.getLocalSocketAddress(), ex);
  67. }
  68. throw new SocketException((InetSocketAddress) client.getLocalSocketAddress(),
  69. "DirectSocket directSupplier error");
  70. }
  71.  
  72. public void closeSocket() {
  73. owner.getTracer().info("client close socket[%s->%s]..", Sockets.getId(stream.getSocket(), false),
  74. Sockets.getId(stream.getSocket(), true));
  75. owner.clients.remove(this);
  76. stream.close();
  77. }
  78.  
  79. public void closeToSocket(boolean pooling) {
  80. owner.getTracer().info("client %s socket[%s->%s]..", pooling ? "pooling" : "close",
  81. Sockets.getId(toStream.getSocket(), false), Sockets.getId(toStream.getSocket(), true));
  82. if (pooling) {
  83. try {
  84. toSock.close();
  85. } catch (Exception ex) {
  86. ex.printStackTrace();
  87. }
  88. } else {
  89. Sockets.close(toStream.getSocket());
  90. }
  91. }
  92. }
  93.  
  94. public static final SocketSupplier HttpSupplier = pack -> {
  95. String line = Bytes.readLine(pack.getBuffer());
  96. if (line == null) {
  97. return null;
  98. }
  99. InetSocketAddress authority;
  100. try {
  101. authority = Sockets.parseEndpoint(
  102. new URL(line.split(" ")[1])
  103. .getAuthority());
  104. } catch (MalformedURLException ex) {
  105. throw SystemException.wrap(ex);
  106. }
  107. SocketPool.PooledSocket pooledSocket = App.retry(2,
  108. p -> SocketPool.Pool.borrowSocket(p),
  109. authority);
  110. return Tuple.of(pooledSocket, pooledSocket.socket);
  111. };
  112. private static final int DefaultBacklog = 128;
  113. private static final int DefaultConnectRetryCount = 4;
  114. private final ServerSocket server;
  115. private final List<ClientItem> clients;
  116. private volatile int connectRetryCount;
  117. private InetSocketAddress directAddress;
  118. private SocketSupplier directSupplier;
  119.  
  120. @Override
  121. public boolean isClosed() {
  122. return !(!super.isClosed() && !server.isClosed());
  123. }
  124.  
  125. public InetSocketAddress getLocalAddress() {
  126. return (InetSocketAddress) server.getLocalSocketAddress();
  127. }
  128.  
  129. public NQuery<Tuple<Socket, Socket>> getClients() {
  130. return NQuery.of(clients).select(p -> Tuple.of(p.stream.getSocket(), p.toStream.getSocket()));
  131. }
  132.  
  133. public int getConnectRetryCount() {
  134. return connectRetryCount;
  135. }
  136.  
  137. public void setConnectRetryCount(int connectRetryCount) {
  138. if (connectRetryCount <= 0) {
  139. connectRetryCount = 1;
  140. }
  141. this.connectRetryCount = connectRetryCount;
  142. }
  143.  
  144. public DirectSocket(int listenPort, InetSocketAddress directAddr) {
  145. this(new InetSocketAddress(Sockets.AnyAddress, listenPort), directAddr, null);
  146. }
  147.  
  148. public DirectSocket(InetSocketAddress listenAddr, InetSocketAddress directAddr, SocketSupplier directSupplier) {
  149. require(listenAddr);
  150. require(this, directAddr != null || directSupplier != null);
  151.  
  152. try {
  153. server = new ServerSocket();
  154. server.setReuseAddress(true);
  155. server.bind(listenAddr, DefaultBacklog);
  156. } catch (IOException ex) {
  157. throw new SocketException(listenAddr, ex);
  158. }
  159. directAddress = directAddr;
  160. this.directSupplier = directSupplier;
  161. clients = Collections.synchronizedList(new ArrayList<>());
  162. connectRetryCount = DefaultConnectRetryCount;
  163. String taskName = String.format("DirectSocket[%s->%s]", listenAddr, isNull(directAddress, "autoAddress"));
  164. LogWriter tracer = new LogWriter();
  165. tracer.setPrefix(taskName + " ");
  166. setTracer(tracer);
  167. AsyncTask.TaskFactory.run(() -> {
  168. getTracer().info("start..");
  169. while (!isClosed()) {
  170. try {
  171. ClientItem client = new ClientItem(server.accept(), this);
  172. clients.add(client);
  173. onReceive(client, taskName);
  174. } catch (IOException ex) {
  175. log.error(taskName, ex);
  176. }
  177. }
  178. close();
  179. }, taskName);
  180. }
  181.  
  182. @Override
  183. protected void freeObjects() {
  184. try {
  185. for (ClientItem client : NQuery.of(clients)) {
  186. client.closeSocket();
  187. }
  188. clients.clear();
  189. server.close();
  190. } catch (IOException ex) {
  191. log.error("DirectSocket close", ex);
  192. }
  193. getTracer().info("stop..");
  194. }
  195.  
  196. private void onReceive(ClientItem client, String taskName) {
  197. AsyncTask.TaskFactory.run(() -> {
  198. try {
  199. int recv = client.stream.directTo(client.toStream, (p1, p2) -> {
  200. getTracer().info("sent %s bytes from %s to %s..", p2,
  201. Sockets.getId(client.stream.getSocket(), true),
  202. Sockets.getId(client.toStream.getSocket(), false));
  203. return true;
  204. });
  205. getTracer().info("socket[%s->%s] closing with %s", Sockets.getId(client.stream.getSocket(), false),
  206. Sockets.getId(client.stream.getSocket(), true), recv);
  207. } catch (SystemException ex) {
  208. $<java.net.SocketException> out = $();
  209. if (ex.tryGet(out, java.net.SocketException.class)) {
  210. if (out.v.getMessage().contains("Socket closed")) {
  211. //ignore
  212. log.debug("DirectTo ignore socket closed");
  213. return;
  214. }
  215. }
  216. throw ex;
  217. } finally {
  218. client.closeSocket();
  219. }
  220. }, String.format("%s[networkStream]", taskName));
  221. AsyncTask.TaskFactory.run(() -> {
  222. int recv = NetworkStream.StreamEOF;
  223. try {
  224. recv = client.toStream.directTo(client.stream, (p1, p2) -> {
  225. getTracer().info("recv %s bytes from %s to %s..", p2,
  226. Sockets.getId(client.toStream.getSocket(), false),
  227. Sockets.getId(client.stream.getSocket(), true));
  228. return true;
  229. });
  230. getTracer().info("socket[%s->%s] closing with %s", Sockets.getId(client.toStream.getSocket(), false),
  231. Sockets.getId(client.toStream.getSocket(), true), recv);
  232. } catch (SystemException ex) {
  233. $<java.net.SocketException> out = $();
  234. if (ex.tryGet(out, java.net.SocketException.class)) {
  235. if (out.v.getMessage().contains("Socket closed")) {
  236. //ignore
  237. log.debug("DirectTo ignore socket closed");
  238. return;
  239. }
  240. }
  241. throw ex;
  242. } finally {
  243. client.closeToSocket(recv == NetworkStream.CannotWrite);
  244. }
  245. }, String.format("%s[toNetworkStream]", taskName));
  246. }
  247. }
  1. package org.rx.socks;
  2.  
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.rx.util.BytesSegment;
  5. import org.rx.io.IOStream;
  6.  
  7. import java.io.IOException;
  8. import java.net.Socket;
  9.  
  10. import static org.rx.core.Contract.require;
  11. import static org.rx.socks.Sockets.shutdown;
  12.  
  13. @Slf4j
  14. public final class NetworkStream extends IOStream {
  15. @FunctionalInterface
  16. public interface DirectPredicate {
  17. boolean test(BytesSegment buffer, int count);
  18. }
  19.  
  20. public static final int SocketEOF = 0;
  21. public static final int StreamEOF = -1;
  22. public static final int CannotWrite = -2;
  23. private final boolean ownsSocket;
  24. private final Socket socket;
  25. private final BytesSegment segment;
  26.  
  27. public boolean isConnected() {
  28. return !isClosed() && !socket.isClosed() && socket.isConnected();
  29. }
  30.  
  31. @Override
  32. public boolean canRead() {
  33. return super.canRead() && checkSocket(socket, false);
  34. }
  35.  
  36. @Override
  37. public boolean canWrite() {
  38. return super.canWrite() && checkSocket(socket, true);
  39. }
  40.  
  41. private static boolean checkSocket(Socket sock, boolean isWrite) {
  42. return !sock.isClosed() && sock.isConnected() && !(isWrite ? sock.isOutputShutdown() : sock.isInputShutdown());
  43. }
  44.  
  45. public Socket getSocket() {
  46. return socket;
  47. }
  48.  
  49. public BytesSegment getSegment() {
  50. return segment;
  51. }
  52.  
  53. public NetworkStream(Socket socket, BytesSegment segment) throws IOException {
  54. this(socket, segment, true);
  55. }
  56.  
  57. public NetworkStream(Socket socket, BytesSegment segment, boolean ownsSocket) throws IOException {
  58. super(socket.getInputStream(), socket.getOutputStream());
  59.  
  60. this.ownsSocket = ownsSocket;
  61. this.socket = socket;
  62. this.segment = segment;
  63. }
  64.  
  65. @Override
  66. protected void freeObjects() {
  67. try {
  68. log.info("NetworkStream freeObjects ownsSocket={} socket[{}][closed={}]", ownsSocket,
  69. Sockets.getId(socket, false), socket.isClosed());
  70. if (ownsSocket) {
  71. //super.freeObjects(); Ignore this!!
  72. Sockets.close(socket, 1);
  73. }
  74. } finally {
  75. segment.close();
  76. }
  77. }
  78.  
  79. int readSegment() {
  80. return read(segment.array, segment.offset, segment.count);
  81. }
  82.  
  83. void writeSegment(int count) {
  84. write(segment.array, segment.offset, count);
  85. }
  86.  
  87. public int directTo(NetworkStream to, DirectPredicate onEach) {
  88. checkNotClosed();
  89. require(to);
  90.  
  91. int recv = StreamEOF;
  92. while (canRead() && (recv = read(segment.array, segment.offset, segment.count)) >= -1) {
  93. if (recv <= 0) {
  94. if (ownsSocket) {
  95. log.debug("DirectTo read {} flag and shutdown send", recv);
  96. shutdown(socket, 1);
  97. }
  98. break;
  99. }
  100.  
  101. if (!to.canWrite()) {
  102. log.debug("DirectTo read {} bytes and can't write", recv);
  103. recv = CannotWrite;
  104. break;
  105. }
  106. to.write(segment.array, segment.offset, recv);
  107.  
  108. if (onEach != null && !onEach.test(segment, recv)) {
  109. recv = StreamEOF;
  110. break;
  111. }
  112. }
  113. if (to.canWrite()) {
  114. to.flush();
  115. }
  116. return recv;
  117. }
  118. }
  1. package org.rx.socks;
  2.  
  3. import org.rx.core.SystemException;
  4.  
  5. import java.net.InetSocketAddress;
  6.  
  7. public class SocketException extends SystemException {
  8. private InetSocketAddress localAddress;
  9.  
  10. public InetSocketAddress getLocalAddress() {
  11. return localAddress;
  12. }
  13.  
  14. public SocketException(InetSocketAddress localAddress, Exception ex) {
  15. super(ex);
  16. this.localAddress = localAddress;
  17. }
  18.  
  19. public SocketException(InetSocketAddress localAddress, String msg) {
  20. super(msg);
  21. this.localAddress = localAddress;
  22. }
  23. }
  1. package org.rx.socks;
  2.  
  3. import java.io.IOException;
  4. import java.net.*;
  5.  
  6. import io.netty.bootstrap.Bootstrap;
  7. import io.netty.buffer.Unpooled;
  8. import io.netty.channel.Channel;
  9. import io.netty.channel.ChannelFutureListener;
  10. import io.netty.channel.EventLoopGroup;
  11. import io.netty.channel.ServerChannel;
  12. import io.netty.channel.epoll.Epoll;
  13. import io.netty.channel.epoll.EpollEventLoopGroup;
  14. import io.netty.channel.epoll.EpollServerSocketChannel;
  15. import io.netty.channel.epoll.EpollSocketChannel;
  16. import io.netty.channel.nio.NioEventLoopGroup;
  17. import io.netty.channel.socket.nio.NioServerSocketChannel;
  18. import io.netty.channel.socket.nio.NioSocketChannel;
  19. import org.rx.core.Strings;
  20. import org.rx.core.SystemException;
  21. import org.rx.core.WeakCache;
  22. import org.springframework.util.CollectionUtils;
  23.  
  24. import java.util.List;
  25. import java.util.Properties;
  26. import java.util.function.Function;
  27.  
  28. import static org.rx.core.Contract.require;
  29. import static org.rx.core.Contract.values;
  30.  
  31. public final class Sockets {
  32. public static final InetAddress LocalAddress, AnyAddress;
  33.  
  34. static {
  35. LocalAddress = InetAddress.getLoopbackAddress();
  36. try {
  37. AnyAddress = InetAddress.getByName("0.0.0.0");
  38. } catch (Exception ex) {
  39. throw SystemException.wrap(ex);
  40. }
  41. }
  42.  
  43. public InetAddress[] getAddresses(String host) {
  44. return (InetAddress[]) WeakCache.getOrStore("Sockets.getAddresses", values(host), p -> {
  45. try {
  46. return InetAddress.getAllByName(host);
  47. } catch (UnknownHostException ex) {
  48. throw SystemException.wrap(ex);
  49. }
  50. });
  51. }
  52.  
  53. public static InetSocketAddress getAnyEndpoint(int port) {
  54. return new InetSocketAddress(AnyAddress, port);
  55. }
  56.  
  57. public static InetSocketAddress parseEndpoint(String endpoint) {
  58. require(endpoint);
  59.  
  60. String[] arr = Strings.split(endpoint, ":", 2);
  61. return new InetSocketAddress(arr[0], Integer.parseInt(arr[1]));
  62. }
  63.  
  64. public static void writeAndFlush(Channel channel, Object... packs) {
  65. require(channel);
  66.  
  67. channel.eventLoop().execute(() -> {
  68. for (Object pack : packs) {
  69. channel.write(pack);
  70. }
  71. channel.flush();
  72. });
  73. }
  74.  
  75. public static EventLoopGroup bossEventLoop() {
  76. return eventLoopGroup(1);
  77. }
  78.  
  79. public static EventLoopGroup workEventLoop() {
  80. return eventLoopGroup(0);
  81. }
  82.  
  83. public static EventLoopGroup eventLoopGroup(int threadAmount) {
  84. return Epoll.isAvailable() ? new EpollEventLoopGroup(threadAmount) : new NioEventLoopGroup(threadAmount); //NioEventLoopGroup(0, TaskFactory.getExecutor());
  85. }
  86.  
  87. public static Bootstrap bootstrap() {
  88. return bootstrap(getChannelClass());
  89. }
  90.  
  91. public static Bootstrap bootstrap(Class<? extends Channel> channelClass) {
  92. require(channelClass);
  93.  
  94. return new Bootstrap().group(channelClass.getName().startsWith("Epoll") ? new EpollEventLoopGroup() : new NioEventLoopGroup()).channel(channelClass);
  95. }
  96.  
  97. public static Bootstrap bootstrap(Channel channel) {
  98. require(channel);
  99.  
  100. return new Bootstrap().group(channel.eventLoop()).channel(channel.getClass());
  101. }
  102.  
  103. public static Class<? extends ServerChannel> getServerChannelClass() {
  104. return Epoll.isAvailable() ? EpollServerSocketChannel.class : NioServerSocketChannel.class;
  105. }
  106.  
  107. public static Class<? extends Channel> getChannelClass() {
  108. return Epoll.isAvailable() ? EpollSocketChannel.class : NioSocketChannel.class;
  109. }
  110.  
  111. public static void closeOnFlushed(Channel channel) {
  112. require(channel);
  113.  
  114. if (!channel.isActive()) {
  115. return;
  116. }
  117. channel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
  118. }
  119.  
  120. public static void close(Socket socket) {
  121. close(socket, 1 | 2);
  122. }
  123.  
  124. public static void close(Socket socket, int flags) {
  125. require(socket);
  126.  
  127. if (!socket.isClosed()) {
  128. shutdown(socket, flags);
  129. try {
  130. socket.setSoLinger(true, 2);
  131. socket.close();
  132. } catch (IOException ex) {
  133. throw SystemException.wrap(ex);
  134. }
  135. }
  136. }
  137.  
  138. /**
  139. * @param socket
  140. * @param flags Send=1, Receive=2
  141. */
  142. public static void shutdown(Socket socket, int flags) {
  143. require(socket);
  144.  
  145. if (!socket.isClosed() && socket.isConnected()) {
  146. try {
  147. if ((flags & 1) == 1 && !socket.isOutputShutdown()) {
  148. socket.shutdownOutput();
  149. }
  150. if ((flags & 2) == 2 && !socket.isInputShutdown()) {
  151. socket.shutdownInput();
  152. }
  153. } catch (IOException ex) {
  154. throw SystemException.wrap(ex);
  155. }
  156. }
  157. }
  158.  
  159. public static String getId(Socket sock, boolean isRemote) {
  160. require(sock);
  161.  
  162. InetSocketAddress addr = (InetSocketAddress) (isRemote ? sock.getRemoteSocketAddress()
  163. : sock.getLocalSocketAddress());
  164. return addr.getHostString() + ":" + addr.getPort();
  165. }
  166.  
  167. public static <T> T httpProxyInvoke(String proxyAddr, Function<String, T> func) {
  168. setHttpProxy(proxyAddr);
  169. try {
  170. return func.apply(proxyAddr);
  171. } finally {
  172. clearHttpProxy();
  173. }
  174. }
  175.  
  176. public static void setHttpProxy(String proxyAddr) {
  177. setHttpProxy(proxyAddr, null, null, null);
  178. }
  179.  
  180. public static void setHttpProxy(String proxyAddr, List<String> nonProxyHosts, String userName, String password) {
  181. InetSocketAddress ipe = parseEndpoint(proxyAddr);
  182. Properties prop = System.getProperties();
  183. prop.setProperty("http.proxyHost", ipe.getAddress().getHostAddress());
  184. prop.setProperty("http.proxyPort", String.valueOf(ipe.getPort()));
  185. prop.setProperty("https.proxyHost", ipe.getAddress().getHostAddress());
  186. prop.setProperty("https.proxyPort", String.valueOf(ipe.getPort()));
  187. if (!CollectionUtils.isEmpty(nonProxyHosts)) {
  188. //如"localhost|192.168.0.*"
  189. prop.setProperty("http.nonProxyHosts", String.join("|", nonProxyHosts));
  190. }
  191. if (userName != null && password != null) {
  192. Authenticator.setDefault(new UserAuthenticator(userName, password));
  193. }
  194. }
  195.  
  196. public static void clearHttpProxy() {
  197. System.clearProperty("http.proxyHost");
  198. System.clearProperty("http.proxyPort");
  199. System.clearProperty("https.proxyHost");
  200. System.clearProperty("https.proxyPort");
  201. System.clearProperty("http.nonProxyHosts");
  202. }
  203.  
  204. static class UserAuthenticator extends Authenticator {
  205. private String userName;
  206. private String password;
  207.  
  208. public UserAuthenticator(String userName, String password) {
  209. this.userName = userName;
  210. this.password = password;
  211. }
  212.  
  213. protected PasswordAuthentication getPasswordAuthentication() {
  214. return new PasswordAuthentication(userName, password.toCharArray());
  215. }
  216. }
  217. }

Java BIO socket的更多相关文章

  1. JAVA BIO与NIO、AIO的区别

    IO的方式通常分为几种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. 一.BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSock ...

  2. java bio 之聊天室

    最近在复习java io相关知识 ,发现很多细节之前没学习到位,原理也没吃透,只能感叹本人愚钝. 复习到bio,顺手写了个简单的聊天室功能,并和大家分享下. 服务端: package io.QQ聊天室 ...

  3. Java BIO及实现

    发现日常学习过的知识不久就会遗忘,在此只是整理并记录一下学习笔记,做个回忆,并方便以后查阅,若有错误,欢迎指正 网络模型:TCP/IP网络模型是从OSI七层模型中演化来的,osi模型分为物理层,数据链 ...

  4. 3. 彤哥说netty系列之Java BIO NIO AIO进化史

    你好,我是彤哥,本篇是netty系列的第三篇. 欢迎来我的公从号彤哥读源码系统地学习源码&架构的知识. 简介 上一章我们介绍了IO的五种模型,实际上Java只支持其中的三种,即BIO/NIO/ ...

  5. [转帖]JAVA BIO与NIO、AIO的区别(这个容易理解)

    JAVA BIO与NIO.AIO的区别(这个容易理解) https://blog.csdn.net/ty497122758/article/details/78979302 2018-01-05 11 ...

  6. Java BIO NIO 与 AIO

    回顾 上一章我们介绍了操作系统层面的 IO 模型. 阻塞 IO 模型. 非阻塞 IO 模型. IO 复用模型. 信号驱动 IO 模型(用的不多,知道个概念就行). 异步 IO 模型. 并且介绍了 IO ...

  7. 【转】JAVA BIO与NIO、AIO的区别

    Java中IO的模型分为三种,同步阻塞的BIO.同步非阻塞的NIO.异步非阻塞的AIO. BIO[同步阻塞] 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个Ser ...

  8. Java BIO、NIO与AIO的介绍(学习过程)

    Java BIO.NIO与AIO的介绍 因为netty是一个NIO的框架,所以在学习netty的过程中,开始之前.针对于BIO,NIO,AIO进行一个完整的学习. 学习资源分享: Netty学习:ht ...

  9. Netty之JAVA BIO模型

    一.JAVA BIO模型 1.I/O模型 I/O 模型简单的理解:就是用什么样的通道进行数据的发送和接收,很大程度上决定了程序通信的性能 Java 共支持 3 种网络编程模型/IO 模式:BIO.NI ...

随机推荐

  1. AtCoder Grand Contest 012 A - AtCoder Group Contest(贪心)

    Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statement There are 3N participa ...

  2. 高并发大流量专题---3、前端优化(减少HTTP请求次数)

    高并发大流量专题---3.前端优化(减少HTTP请求次数) 一.总结 一句话总结: 图片地图:使用<map><area></area></map>标签. ...

  3. vijos 1243 生产产品

    貌似两年前联赛复习的时候就看过这题 然而当时大概看看了 感觉太难 便没有去做 如今再去做的时候 发现其实也并不容易 ------------------------------------------ ...

  4. css控制显示超出多少行以后开始出现省略号的写法

    display: -webkit-box; display: -moz-box; text-overflow: -o-ellipsis-lastline; text-overflow: ellipsi ...

  5. 2.2寸(14PIN)TFT液晶屏STM32 SPI 控制

    屏幕如图所示,共14个IO口(也可能只有13个),控制屏幕的有9个IO口 详细版介绍见:http://www.ciast.net/post/20151112.html 反面IO口图: 连接通过SPI方 ...

  6. UVA12589_Learning Vector

    大致题意: 有n个向量要你选k个,把这k个向量连起来,画出来的与x轴围成的面积最大 思路: 这个是斜率dp,让斜率大的排在前面,记忆化搜索的时候要加入一个当前高的信息,因为这个向量形成面积不仅和斜率有 ...

  7. C++中的抽象类和接口

    1,在 C++ 语言中,并不直接支持面向对象中的抽象类和接口概念,但是 C++ 语言 却可以间接实现这些概念: 2,什么是抽象类: 1,面向对象中的抽象(其实就是分类)概念: 1,在进行面向对象分析时 ...

  8. MATLAB之画确定区域内互不接触的球

    MATLAB之画确定区域内互不接触的球 程序要求:在确定区域内,画互不接触的球 输入:球的个数N,半径D,两球之间的最小距离K倍(D的倍数) 输出:各圆心的三维坐标,并作图显示 程序: functio ...

  9. java树的遍历

    java二叉树的遍历算法: http://blog.sina.com.cn/s/blog_70600f720100ujnp.html

  10. vue证明题五,组件传值与绑定

    上文中写了一个input组件,该组件需要复用,但是并不是每个组件都相同的 比如我定义了一个组件,是个矿泉水瓶子,这个瓶子分为大中小三个号,定义了三种瓶子的容积,定义了必须有瓶盖,瓶口,瓶子质地 但是瓶 ...