From cc030e3c07a75f0db0a001d1e2ce52c2101e9776 Mon Sep 17 00:00:00 2001 From: olivierayache Date: Thu, 9 Jan 2020 18:31:56 +0100 Subject: [PATCH] Use socket isConnected() method rather than isBound() before connect to server. Fixes #962 --- .../client/WebSocketClient.java | 2 +- .../java_websocket/issues/AllIssueTests.java | 3 +- .../java_websocket/issues/Issue962Test.java | 143 ++++++++++++++++++ 3 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 src/test/java/org/java_websocket/issues/Issue962Test.java diff --git a/src/main/java/org/java_websocket/client/WebSocketClient.java b/src/main/java/org/java_websocket/client/WebSocketClient.java index c88f258f..756e5721 100644 --- a/src/main/java/org/java_websocket/client/WebSocketClient.java +++ b/src/main/java/org/java_websocket/client/WebSocketClient.java @@ -457,7 +457,7 @@ public void run() { socket.setTcpNoDelay( isTcpNoDelay() ); socket.setReuseAddress( isReuseAddr() ); - if (!socket.isBound()) { + if (!socket.isConnected()) { InetSocketAddress addr = new InetSocketAddress(dnsResolver.resolve(uri), this.getPort()); socket.connect(addr, connectTimeout); } diff --git a/src/test/java/org/java_websocket/issues/AllIssueTests.java b/src/test/java/org/java_websocket/issues/AllIssueTests.java index 3e6fb5b4..3be0995a 100644 --- a/src/test/java/org/java_websocket/issues/AllIssueTests.java +++ b/src/test/java/org/java_websocket/issues/AllIssueTests.java @@ -42,7 +42,8 @@ org.java_websocket.issues.Issue764Test.class, org.java_websocket.issues.Issue765Test.class, org.java_websocket.issues.Issue825Test.class, - org.java_websocket.issues.Issue834Test.class + org.java_websocket.issues.Issue834Test.class, + org.java_websocket.issues.Issue962Test.class }) /** * Start all tests for issues diff --git a/src/test/java/org/java_websocket/issues/Issue962Test.java b/src/test/java/org/java_websocket/issues/Issue962Test.java new file mode 100644 index 00000000..09263fff --- /dev/null +++ b/src/test/java/org/java_websocket/issues/Issue962Test.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2010-2019 Olivier Ayache + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +package org.java_websocket.issues; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.UnknownHostException; +import javax.net.SocketFactory; +import org.java_websocket.WebSocket; +import org.java_websocket.client.WebSocketClient; +import org.java_websocket.handshake.ClientHandshake; +import org.java_websocket.handshake.ServerHandshake; +import org.java_websocket.server.WebSocketServer; +import org.java_websocket.util.SocketUtil; +import org.junit.Assert; +import org.junit.Test; + +public class Issue962Test { + + private static class TestSocketFactory extends SocketFactory { + + private final SocketFactory socketFactory = SocketFactory.getDefault(); + private final String bindingAddress; + + public TestSocketFactory(String bindingAddress) { + this.bindingAddress = bindingAddress; + } + + @Override + public Socket createSocket() throws IOException { + Socket socket = socketFactory.createSocket(); + socket.bind(new InetSocketAddress(bindingAddress, 0)); + return socket; + } + + @Override + public Socket createSocket(String string, int i) throws IOException, UnknownHostException { + Socket socket = socketFactory.createSocket(string, i); + socket.bind(new InetSocketAddress(bindingAddress, 0)); + return socket; + } + + @Override + public Socket createSocket(String string, int i, InetAddress ia, int i1) throws IOException, UnknownHostException { + throw new UnsupportedOperationException(); + } + + @Override + public Socket createSocket(InetAddress ia, int i) throws IOException { + Socket socket = socketFactory.createSocket(ia, i); + socket.bind(new InetSocketAddress(bindingAddress, 0)); + return socket; + } + + @Override + public Socket createSocket(InetAddress ia, int i, InetAddress ia1, int i1) throws IOException { + throw new UnsupportedOperationException(); + } + + } + + @Test + public void testIssue() throws IOException, URISyntaxException, InterruptedException { + int port = SocketUtil.getAvailablePort(); + WebSocketClient client = new WebSocketClient(new URI("ws://127.0.0.1:" + port)) { + @Override + public void onOpen(ServerHandshake handshakedata) { + } + + @Override + public void onMessage(String message) { + } + + @Override + public void onClose(int code, String reason, boolean remote) { + } + + @Override + public void onError(Exception ex) { + Assert.fail(ex.toString() + " sould not occur"); + } + }; + + String bindingAddress = "127.0.0.1"; + + client.setSocketFactory(new TestSocketFactory(bindingAddress)); + + WebSocketServer server = new WebSocketServer(new InetSocketAddress(port)) { + @Override + public void onOpen(WebSocket conn, ClientHandshake handshake) { + } + + @Override + public void onClose(WebSocket conn, int code, String reason, boolean remote) { + } + + @Override + public void onMessage(WebSocket conn, String message) { + } + + @Override + public void onError(WebSocket conn, Exception ex) { + } + + @Override + public void onStart() { + } + }; + + server.start(); + client.connectBlocking(); + Assert.assertEquals(bindingAddress, client.getSocket().getLocalAddress().getHostAddress()); + Assert.assertNotEquals(0, client.getSocket().getLocalPort()); + Assert.assertTrue(client.getSocket().isConnected()); + } + +}