提交 43c91a62 authored 作者: Sergi Vladykin's avatar Sergi Vladykin

Added workaround for Windows problem with frequent socket connections.

上级 cb63bf48
......@@ -102,13 +102,21 @@ public class NetUtils {
* @return the socket
*/
public static Socket createSocket(InetAddress address, int port, boolean ssl) throws IOException {
if (ssl) {
return SecureSocketFactory.createSocket(address, port);
for (;;) {
try {
if (ssl) {
return SecureSocketFactory.createSocket(address, port);
}
Socket socket = new Socket();
socket.connect(new InetSocketAddress(address, port),
SysProperties.SOCKET_CONNECT_TIMEOUT);
return socket;
} catch (BindException e) {
// Workaround for Windows problem with frequent connections:
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213296
// trying to connect again
}
}
Socket socket = new Socket();
socket.connect(new InetSocketAddress(address, port),
SysProperties.SOCKET_CONNECT_TIMEOUT);
return socket;
}
/**
......
......@@ -117,6 +117,7 @@ import org.h2.test.unit.TestFtp;
import org.h2.test.unit.TestIntArray;
import org.h2.test.unit.TestIntIntHashMap;
import org.h2.test.unit.TestMathUtils;
import org.h2.test.unit.TestNetUtils;
import org.h2.test.unit.TestOverflow;
import org.h2.test.unit.TestPageStore;
import org.h2.test.unit.TestPattern;
......@@ -594,6 +595,7 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
new TestIntArray().runTest(this);
new TestIntIntHashMap().runTest(this);
new TestMathUtils().runTest(this);
new TestNetUtils().runTest(this);
new TestMultiThreadedKernel().runTest(this);
new TestOverflow().runTest(this);
new TestPageStore().runTest(this);
......
/**
*
*/
package org.h2.test.unit;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import org.h2.engine.Constants;
import org.h2.test.TestBase;
import org.h2.util.NetUtils;
/**
* @author Sergi Vladykin
*/
public class TestNetUtils extends TestBase {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
TestBase.createCaller().init().test();
}
@Override
public void test() throws Exception {
testFrequentConnections(false);
testFrequentConnections(true);
}
private void testFrequentConnections(boolean ssl) throws Exception {
final ServerSocket serverSock = NetUtils.createServerSocket(Constants.DEFAULT_TCP_PORT, ssl);
Thread serverThread = new Thread() {
@Override
public void run() {
while (!isInterrupted()) {
try {
Socket socket = serverSock.accept();
socket.close();
} catch (Exception e) {
// ignore
}
}
}
};
serverThread.start();
// System.out.println("Server started.");
AtomicInteger counter = new AtomicInteger();
try {
Set<ConnectWorker> workers = new HashSet<ConnectWorker>();
for (int i = 0; i < 10; i++) {
workers.add(new ConnectWorker(ssl, workers, counter));
}
for (ConnectWorker worker : workers) {
worker.start();
}
// System.out.println("Workers started.");
Exception exception = null;
for (ConnectWorker worker : workers) {
worker.join();
if (exception == null) {
exception = worker.getException();
// if (exception != null) {
// System.out.println("Exception set.");
// }
}
}
// System.out.println("All joined.");
if (exception != null) {
throw exception;
}
} finally {
serverThread.interrupt();
try {
serverSock.close();
} catch (Exception e) {
// ignore
}
// System.out.println("Server stopped.");
}
}
/**
*
*/
private class ConnectWorker extends Thread {
private static final int MAX_CONNECT_COUNT = 10000;
private final boolean ssl;
private final Set<ConnectWorker> workers;
private final AtomicInteger counter;
private volatile Exception exception;
public ConnectWorker(boolean ssl, Set<ConnectWorker> workers, AtomicInteger counter) {
this.ssl = ssl;
this.workers = workers;
this.counter = counter;
}
@Override
public void run() {
try {
while (!isInterrupted() && counter.incrementAndGet() < MAX_CONNECT_COUNT) {
Socket sock = NetUtils.createSocket("127.0.0.1", Constants.DEFAULT_TCP_PORT, ssl);
// System.out.println(COUNTER.get());
try {
sock.close();
} catch (IOException e) {
// ignore
}
}
} catch (Exception e) {
this.exception = e;
for (ConnectWorker worker : workers) {
worker.interrupt();
}
}
}
/**
* @return the exception
*/
public Exception getException() {
return exception;
}
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论