我有一个用于JUnit 4.x的Java类。在每个@Test方法中,我创建了一个新的HttpServer,使用了端口9090。第一个调用工作找到,但后续的错误“地址已经在使用:绑定”。
以下是一个例子:
@Test
public void testSendNoDataHasValidResponse() throws Exception {
InetSocketAddress address = new InetSocketAddress(9090);
HttpHandler handler = new HttpHandler() {
@Override
public void handle(HttpExchange exchange) throws IOException {
byte[] response = "Hello, world".getBytes();
exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.length);
exchange.getResponseBody().write(response);
exchange.close();
}
};
HttpServer server = HttpServer.create(address, 1);
server.createContext("/me.html", handler);
server.start();
Client client = new Client.Builder(new URL("http://localhost:9090/me.html"), 20, "mykey").build();
client.sync();
server.stop(1);
assertEquals(true, client.isSuccessfullySynchronized());
}
显然,HttpServer仅在每个方法中保存,并在结束前停止。我没有看到什么继续保持任何套接字打开。第一次测试通过,后续测试每次都失败。
有什么想法吗?
使用更正方法编辑:
@Test
public void testSendNoDataHasValidResponse() throws Exception {
server = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 1);
HttpHandler handler = new HttpHandler() {
@Override
public void handle(HttpExchange exchange) throws IOException {
byte[] response = "Hello, world".getBytes();
exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.length);
exchange.getResponseBody().write(response);
exchange.close();
}
};
server.createContext("/me.html", handler);
server.start();
InetSocketAddress address = server.getAddress();
String target = String.format("http://%s:%s/me.html", address.getHostName(), address.getPort());
Client client = new Client.Builder(new URL(target), 20, "mykey").build();
client.sync();
server.stop(0);
assertEquals(true, client.isSuccessfullySynchronized());
}
答案 0 :(得分:5)
其他解决方法:
为所有测试重用相同的HttpServer。要在测试之间清理它,您可以删除它的所有上下文。如果你给它一个自定义执行程序,你也可以等待或终止所有工作程序线程。
在新端口上创建每个HttpServer。您可以specifying a port number of zero when creating the InetSocketAddress执行此操作。然后,您可以在创建后找到querying the server for its port使用的实际端口,并在测试中使用它。
Change the global server socket factory到自定义工厂,每次都返回相同的服务器套接字。这使得您可以为许多测试重用相同的实际套接字,而无需重用HttpServer。
答案 1 :(得分:3)
通常需要2分钟的等待时间才能重新绑定到特定的端口号。运行netstat以确认您的服务器连接是否在TIME_WAIT中。如果是这样,您可以在绑定之前使用SO_REUSEADDR选项绕过它。对于java,文档是here。
答案 2 :(得分:0)
创建HttpServer时,指定了
允许的最大排队传入连接数 听插座
1
server = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 1);