Java socketRead0 问题

标签 java sockets

我正在使用 htmlunit 开发一个 web cralwer 并且我已经添加了所有必需的超时但是我注意到当我使用 Java VisualVM 进行线程转储时某些网站的服务器没有响应时应用程序挂起:

java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at java.net.SocksSocketImpl.readSocksReply(SocksSocketImpl.java:88)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:429)
at java.net.Socket.connect(Socket.java:525)
at com.gargoylesoftware.htmlunit.SocksSocketFactory.connectSocket(SocksSocketFactory.java:89)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:148)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:121)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:573)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:425)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:776)
at com.gargoylesoftware.htmlunit.HttpWebConnection.getResponse(HttpWebConnection.java:152)
at app.plugin.core.net.QHttpWebConnection.getResponse(QHttpWebConnection.java:30)
at com.gargoylesoftware.htmlunit.WebClient.loadWebResponseFromWebConnection(WebClient.java:1439)
at com.gargoylesoftware.htmlunit.WebClient.loadWebResponse(WebClient.java:1358)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:307)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:373)
at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:358)

这真的很令人沮丧,因为我无法控制这些服务器。这个问题严重影响了我的应用程序的性能。

问题:

  1. 我该如何解决这个问题?
  2. 有没有办法获取 Java 应用程序打开的套接字连接列表并使用它来终止套接字,例如模拟服务器关闭连接?

最佳答案

我相信,当您使用 Java native 方法时,堆栈跟踪会显示 RUNNABLE,即使调用实际上已被阻止等待某个事件。本质上,我不相信 Java 有任何方式知道本地方法实际在做什么,所以它将这些调用标记为 RUNNABLE。我在 socketRead0() 和 socketAccept() 中看到过这种情况——它们通常都会阻塞。

您需要将超时设置为合理的时间长度,以便在服务器没有响应时您的请求会超时,但也不能太短以防服务器很忙。您的应用程序应该编写为使用多线程。我会尝试运行十几个或更多线程,并让每个线程等待最多五到十秒的响应。让少数线程等待几乎没有开销。在编写网络蜘蛛时,您还应该注意不要用大量请求轰炸服务器。

关于Java socketRead0 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12544212/

相关文章:

c++ - 由于 sin6_port 值,sendto 在 Linux 中的 UDP 原始套接字 ipv6 上返回无效参数?

html - 如何发送多个数据(conn :send()) with the new SDK (NodeMCU)

java - 如何在控制台上打印整个响应

python - 是否可以在套接字监听器上跟踪丢失的连接?

带有匿名 Diffie Hellman 的 Java SSL/TLS

java - 如何使用java向程序ab添加功能?

java - BufferedReader 返回 null,即使它正在读取的流位于 pos 0

java - 在 Java 中运行 Smirnov 测试

perl - 使用 Perl 的 readline , <> 函数与 TCP 套接字和信号

java - setOnClickListener() 的空指针异常