NutzCN Logo
问答 Http工具类,还是遇到Address already in use: connect问题,怎么破
发布于 2806天前 作者 qq_16dd5808 5247 次浏览 复制 上一个帖子 下一个帖子
标签:

错误信息

38007
甘肃省,金昌市,永昌县,沙帽翅沟(南586米)
38008
甘肃省,金昌市,永昌县,沙帽翅沟(南586米)
38009

java.util.concurrent.ExecutionException: org.nutz.http.HttpException: url=http://192.168.11.169:9094/DiscInfo/getDisc?pointX=101.8016950000&pointY=38.3976280000

	at java.util.concurrent.FutureTask.report(FutureTask.java:122)
	at java.util.concurrent.FutureTask.get(FutureTask.java:192)
	at test.sunyu.tools.http.TestHttpTools.t1(TestHttpTools.java:47)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
Caused by: org.nutz.http.HttpException: url=http://192.168.11.169:9094/DiscInfo/getDisc?pointX=101.8016950000&pointY=38.3976280000
	at org.nutz.http.sender.GetSender.send(GetSender.java:22)
	at org.nutz.http.Http.get(Http.java:144)
	at sunyu.tools.http.HttpTools.get(HttpTools.java:30)
	at test.sunyu.tools.http.TestHttpTools$1.call(TestHttpTools.java:40)
	at test.sunyu.tools.http.TestHttpTools$1.call(TestHttpTools.java:37)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.BindException: Address already in use: connect
	at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
	at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:589)
	at sun.net.NetworkClient.doConnect(NetworkClient.java:175)
	at sun.net.www.http.HttpClient.openServer(HttpClient.java:432)
	at sun.net.www.http.HttpClient.openServer(HttpClient.java:527)
	at sun.net.www.http.HttpClient.<init>(HttpClient.java:211)
	at sun.net.www.http.HttpClient.New(HttpClient.java:308)
	at sun.net.www.http.HttpClient.New(HttpClient.java:326)
	at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:1169)
	at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(HttpURLConnection.java:1105)
	at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:999)
	at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:933)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1513)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
	at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
	at org.nutz.http.Sender.getResponseHeader(Sender.java:137)
	at org.nutz.http.sender.GetSender.send(GetSender.java:19)
	... 8 more

测试代码如下:

@Test
    public void t1() throws ExecutionException, InterruptedException {
        Stopwatch sw = Stopwatch.begin();
        List<Future> list = new ArrayList<>();
        for (int i = 0; i < 1000000; i++) {
            list.add(executorService.submit(new Callable<Response>() {
                @Override
                public Response call() throws Exception {
                    return httpTools.get("http://192.168.11.169:9094/DiscInfo/getDisc?pointX=101.8016950000&pointY=38.3976280000");
                }
            }));
        }
        int i = 0;
        for (Future r : list) {
            System.out.println(++i + "");
            Response response = (Response) r.get();
            System.out.println(response.getContent());
        }
        sw.stop();
        System.out.println(sw.toString());
    }
11 回复

Http.get方法是没有走线程池的

来自炫酷的 NutzCN

@wendal 那有解决方案么?这个接口只能get请求,post请求是没数据的

@qq_16dd5808 用

Sender.create(xxxxx).send(nulll);

来自炫酷的 NutzCN

依然是上次的代码, 没有重现

@wendal
把url改成

"http://192.168.11.169:9094/DiscInfo/getDisc?pointX=101.8016950000&pointY=38.3976280000" + "&t=" + R.UU32()

就可以了,如果改成R.UU16都不行

感觉像是,一下子并发太多,url重复到一定次数,会出现那个问题。

应该是不停地新建连接,导致本地端口分配完了,得研究一下apache http client是怎么解决这个问题的

来自炫酷的 NutzCN

@wendal 经过了几轮测试,发现executorService = Executors.newFixedThreadPool(2);这个值设置越小,就越不容易出现这个问题,当设置2的时候,发送一百万个链接,一个错误都没有。

在回头看
https://nutz.cn/yvr/t/rrgo3lm002gqdrdijohona5jng
这个帖子,发现httpClient使用了defaultMaxPerRoute参数。难道是同一个地址,路由有限制?需要特殊设置

http://docs.oracle.com/javase/1.5.0/docs/guide/net/http-keepalive.html

然后看了看httpclient的源码, 没有使用UrlConnection,而是从Socket一路实现过去

添加回复
请先登陆
回到顶部