线程在socketRead0 Java中挂起

时间:2011-01-05 16:05:59

标签: java sockets

基本上我正在尝试下载网页的HTML内容。方法很简单

        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
        BufferReader in = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
        String line;
        StringBuilder pageBuilder = new StringBuilder();
        while ((line = in.readLine()) != null) {
            pageBuilder.append(line + "\n");
        }

但有时程序会挂起。我试图调试,线程堆栈跟踪告诉我它在调用方法SocketRead0时挂起。我试图为连接设置readtimeout但它不起作用。关于如何检测并通过SocketRead0块的任何想法?

编辑:似乎我实际遇到的问题是getReponseCode隐式调用了一些getInputStream和一些read()方法,然后在readSocket0()处挂起。无论如何我可以确保调用getReponseCode()是安全的吗? 这是一个线程挂起的堆栈跟踪:级别0是最近的一次调用

thread 24stacktrace
        At 0level
        at method socketRead0
        at line -2
        At 1level
        at method read
        at line 129
        At 2level
        at method fill
        at line 218
        At 3level
        at method read1
        at line 258
        At 4level
        at method read
        at line 317
        At 5level
        at method parseHTTPHeader
        at line 687
        At 6level
        at method parseHTTP
        at line 632
        At 7level
        at method getInputStream
        at line 1200
        At 8level
        at method getResponseCode
        at line 379
        At 9level
        at method pushFinalRedirectedURL
        at line 132
        At 10level
        at method process
        at line 134
        At 11level
        at method run
        at line 40

4 个答案:

答案 0 :(得分:2)

套接字读取是一种阻塞操作。它会阻塞,直到有更多数据,到达流的末尾或连接关闭。

答案 1 :(得分:2)

在调用readline函数之前,需要确保缓冲区中有数据要读取。正如彼得所提到的,SocketRead是一个阻塞函数,这意味着当它被调用时,它会坐下来等待数据放到流上。

试试这个:

while (in.ready()) {
    line = in.readLine();
    pageBuilder.append(line + "\n");
}

Here是BufferedReader API的链接。

答案 2 :(得分:2)

我也有这个错误并解决了它。出现此问题的原因是,有时软件会尝试打开与不发送响应的服务器的连接,但也不会给出错误。

该软件仍在等待服务器的回答,但它永远不会出现。

为避免这种情况,您需要使用setConnectTimeout()方法,因此如果服务器未在确定的时间内发送答案,则连接将被中止。

setConnectTimeout() reference

答案 3 :(得分:1)

只是对先前关于套接字读取阻塞的答案的补充: 如果方法private native int socketRead0(FileDescriptor fd, byte b[], int off, int len, int timeout) throws IOException 获取超时0(默认值),不使用超时。因此它可以阻止而不是抛出IOException。