From a6fbc181520f3432b77df752c98685ac99e095a7 Mon Sep 17 00:00:00 2001 From: tywo45 <tywo45@163.com> Date: Fri, 2 Sep 2022 15:01:24 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BD=9C=E4=B8=BATCP=20Clien?= =?UTF-8?q?t=E5=9C=A8=E6=96=AD=E7=BD=91=E7=8A=B6=E6=80=81=E4=B8=8B?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E5=9F=9F=E5=90=8D=E6=97=B6=E6=8A=A5=E7=9A=84?= =?UTF-8?q?=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复作为TCP Client在断网状态下连接域名时报的异常 --- .../org/tio/client/ClientChannelContext.java | 17 +++++- .../main/java/org/tio/client/TioClient.java | 21 ++++--- .../java/org/tio/core/ChannelContext.java | 14 +++-- .../org/tio/core/maintain/ClientNodes.java | 58 +++++++------------ .../org/tio/server/ServerChannelContext.java | 17 +++++- 5 files changed, 73 insertions(+), 54 deletions(-) diff --git a/src/core/src/main/java/org/tio/client/ClientChannelContext.java b/src/core/src/main/java/org/tio/client/ClientChannelContext.java index 47140616..d75b2653 100644 --- a/src/core/src/main/java/org/tio/client/ClientChannelContext.java +++ b/src/core/src/main/java/org/tio/client/ClientChannelContext.java @@ -251,8 +251,21 @@ public ClientChannelContext(TioConfig tioConfig) { */ @Override public Node createClientNode(AsynchronousSocketChannel asynchronousSocketChannel) throws IOException { - InetSocketAddress inetSocketAddress = (InetSocketAddress) asynchronousSocketChannel.getLocalAddress(); - Node clientNode = new Node(inetSocketAddress.getHostString(), inetSocketAddress.getPort()); + Node clientNode = null; + InetSocketAddress inetSocketAddress = null; + if (asynchronousSocketChannel == null) { + clientNode = createUnknowNode(); + } else { + inetSocketAddress = (InetSocketAddress) asynchronousSocketChannel.getLocalAddress(); + } + + if (inetSocketAddress == null) { + clientNode = createUnknowNode(); + } + + if (clientNode == null) { + clientNode = new Node(inetSocketAddress.getHostString(), inetSocketAddress.getPort()); + } return clientNode; } diff --git a/src/core/src/main/java/org/tio/client/TioClient.java b/src/core/src/main/java/org/tio/client/TioClient.java index c65aa6d4..41e4d863 100644 --- a/src/core/src/main/java/org/tio/client/TioClient.java +++ b/src/core/src/main/java/org/tio/client/TioClient.java @@ -390,16 +390,23 @@ private ClientChannelContext connect(Node serverNode, String bindIp, Integer bin CountDownLatch countDownLatch = new CountDownLatch(1); attachment.setCountDownLatch(countDownLatch); - asynchronousSocketChannel.connect(inetSocketAddress, attachment, tioClientConfig.getConnectionCompletionHandler()); - boolean f = countDownLatch.await(realTimeout, TimeUnit.SECONDS); - if (f) { - return attachment.getChannelContext(); - } else { - log.error("countDownLatch.await(realTimeout, TimeUnit.SECONDS) 返回false "); + + try { + asynchronousSocketChannel.connect(inetSocketAddress, attachment, tioClientConfig.getConnectionCompletionHandler()); + } catch (Throwable e) { + tioClientConfig.getConnectionCompletionHandler().failed(e, attachment); return attachment.getChannelContext(); } + + @SuppressWarnings("unused") + boolean f = countDownLatch.await(realTimeout, TimeUnit.SECONDS); + return attachment.getChannelContext(); } else { - asynchronousSocketChannel.connect(inetSocketAddress, attachment, tioClientConfig.getConnectionCompletionHandler()); + try { + asynchronousSocketChannel.connect(inetSocketAddress, attachment, tioClientConfig.getConnectionCompletionHandler()); + } catch (Throwable e) { + tioClientConfig.getConnectionCompletionHandler().failed(e, attachment); + } return null; } } diff --git a/src/core/src/main/java/org/tio/core/ChannelContext.java b/src/core/src/main/java/org/tio/core/ChannelContext.java index b2b2e9d6..b83847bd 100644 --- a/src/core/src/main/java/org/tio/core/ChannelContext.java +++ b/src/core/src/main/java/org/tio/core/ChannelContext.java @@ -211,7 +211,6 @@ recommend that a file or class name and description of purpose be included on import org.tio.core.task.DecodeRunnable; import org.tio.core.task.HandlerRunnable; import org.tio.core.task.SendRunnable; -import org.tio.utils.hutool.CollUtil; import org.tio.utils.hutool.StrUtil; import org.tio.utils.lock.SetWithLock; import org.tio.utils.prop.MapWithLockPropSupport; @@ -322,10 +321,13 @@ public ChannelContext(TioConfig tioConfig, String id) { initOther(); } - - private void assignAnUnknownClientNode() { - Node clientNode = new Node(UNKNOWN_ADDRESS_IP, UNKNOWN_ADDRESS_PORT_SEQ.incrementAndGet()); - setClientNode(clientNode); + + protected void assignAnUnknownClientNode() { + setClientNode(createUnknowNode()); + } + + public static Node createUnknowNode() { + return new Node(UNKNOWN_ADDRESS_IP, UNKNOWN_ADDRESS_PORT_SEQ.incrementAndGet()); } /** @@ -363,6 +365,8 @@ public boolean equals(Object obj) { } return true; } + + /** * 等价于:getAttribute(DEFAULT_ATTUBITE_KEY) diff --git a/src/core/src/main/java/org/tio/core/maintain/ClientNodes.java b/src/core/src/main/java/org/tio/core/maintain/ClientNodes.java index 78e69db3..2b536db3 100644 --- a/src/core/src/main/java/org/tio/core/maintain/ClientNodes.java +++ b/src/core/src/main/java/org/tio/core/maintain/ClientNodes.java @@ -194,6 +194,7 @@ recommend that a file or class name and description of purpose be included on package org.tio.core.maintain; import java.util.Map; +import java.util.Objects; import java.util.concurrent.locks.Lock; import org.slf4j.Logger; @@ -208,52 +209,34 @@ recommend that a file or class name and description of purpose be included on * 2017年4月1日 上午9:35:20 */ public class ClientNodes { - private static Logger log = LoggerFactory.getLogger(ClientNodes.class); + private static final Logger log = LoggerFactory.getLogger(ClientNodes.class); - /** - * - * @param channelContext - * @return - * @author tanyaowu - */ - public static String getKey(ChannelContext channelContext) { - Node clientNode = channelContext.getClientNode(); - if (clientNode == null) { - throw new RuntimeException("client node is null"); - } - String key = getKey(clientNode.getIp(), clientNode.getPort()); - return key; - } + /** remoteAndChannelContext key: Node value: ChannelContext. */ + private final MapWithLock<Node, ChannelContext> mapWithLock = new MapWithLock<>(); /** * - * @param ip - * @param port - * @return + * @param channelContext ChannelContext + * @return Node * @author tanyaowu */ - public static String getKey(String ip, int port) { - String key = ip + ":" + port; - return key; + public static Node getKey(ChannelContext channelContext) { + Node clientNode = channelContext.getClientNode(); + return Objects.requireNonNull(clientNode, "client node is null"); } - /** remoteAndChannelContext key: "ip:port" value: ChannelContext. */ - private MapWithLock<String, ChannelContext> mapWithLock = new MapWithLock<>(); - /** * - * @param key + * @param clientNode * @return * @author tanyaowu */ - public ChannelContext find(String key) { + public ChannelContext find(Node clientNode) { Lock lock = mapWithLock.readLock(); lock.lock(); try { - Map<String, ChannelContext> m = mapWithLock.getObj(); - return m.get(key); - } catch (Throwable e) { - throw e; + Map<Node, ChannelContext> m = mapWithLock.getObj(); + return m.get(clientNode); } finally { lock.unlock(); } @@ -267,8 +250,7 @@ public ChannelContext find(String key) { * @author tanyaowu */ public ChannelContext find(String ip, int port) { - String key = getKey(ip, port); - return find(key); + return find(new Node(ip, port)); } /** @@ -276,13 +258,13 @@ public ChannelContext find(String ip, int port) { * @return * @author tanyaowu */ - public MapWithLock<String, ChannelContext> getObjWithLock() { + public MapWithLock<Node, ChannelContext> getObjWithLock() { return mapWithLock; } /** * 添加映射 - * @param channelContext + * @param channelContext ChannelContext * @author tanyaowu */ public void put(ChannelContext channelContext) { @@ -290,8 +272,8 @@ public void put(ChannelContext channelContext) { return; } try { - String key = getKey(channelContext); - mapWithLock.put(key, channelContext); + Node clientNode = getKey(channelContext); + mapWithLock.put(clientNode, channelContext); } catch (Exception e) { log.error(e.toString(), e); } @@ -307,8 +289,8 @@ public void remove(ChannelContext channelContext) { return; } try { - String key = getKey(channelContext); - mapWithLock.remove(key); + Node clientNode = getKey(channelContext); + mapWithLock.remove(clientNode); } catch (Throwable e) { log.error(e.toString(), e); } diff --git a/src/core/src/main/java/org/tio/server/ServerChannelContext.java b/src/core/src/main/java/org/tio/server/ServerChannelContext.java index 168e8fc3..c35bee8d 100644 --- a/src/core/src/main/java/org/tio/server/ServerChannelContext.java +++ b/src/core/src/main/java/org/tio/server/ServerChannelContext.java @@ -250,8 +250,21 @@ public ServerChannelContext(TioConfig tioConfig, String id) { */ @Override public Node createClientNode(AsynchronousSocketChannel asynchronousSocketChannel) throws IOException { - InetSocketAddress inetSocketAddress = (InetSocketAddress) asynchronousSocketChannel.getRemoteAddress(); - Node clientNode = new Node(inetSocketAddress.getHostString(), inetSocketAddress.getPort()); + Node clientNode = null; + InetSocketAddress inetSocketAddress = null; + if (asynchronousSocketChannel == null) { + clientNode = createUnknowNode(); + } else { + inetSocketAddress = (InetSocketAddress) asynchronousSocketChannel.getRemoteAddress(); + } + + if (inetSocketAddress == null) { + clientNode = createUnknowNode(); + } + + if (clientNode == null) { + clientNode = new Node(inetSocketAddress.getHostString(), inetSocketAddress.getPort()); + } return clientNode; }