当前位置: 首页 > 知识库问答 >
问题:

JAVA网UnknownHostException和java。网SocketException:打开的文件太多

赵锐
2023-03-14

我正在Tomcat上运行一个web应用程序。我的应用程序连接到其他web服务以满足客户端的请求。有时我会得到java。网在打开URL连接时出现UnknownHostException,之后有时我开始使用java。网SocketException:打开的文件太多。我的服务器不再进一步接受连接。请导游。

String  response;
    HttpURLConnection conn = null;
BufferedReader rd = null;
InputStream in = null;
try
{
    // Send data
    String urlStr = URL;
    URL url = new URL(urlStr);
    conn = (HttpURLConnection)url.openConnection();
    conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
    int contentLength = conn.getContentLength();
    //   System.out.println("content length 1" +  contentLength);
    if (contentLength <= 0)
    {
        InputStream in1 = (conn).getErrorStream();
        if (in1 != null)
        {
            in1.close();
        }
        conn.getInputStream().close();
        in = null;
        conn.disconnect();
        conn = null;
        return null;
    }
    in = conn.getInputStream();
    if (conn.getResponseCode() != 200)
    {
        InputStream in1 = (conn).getErrorStream();
        if (in1 != null)
        {
            in1.close();
        }
        conn.getInputStream().close();
        in = null;
        conn.disconnect();
        conn = null;
        in.close();
        in = null;
        return null;
    }
    // Get the response
    rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    StringBuffer stringBuffer = new StringBuffer();
    String line = null;
    while ((line = rd.readLine()) != null)
    {
        stringBuffer.append(line);
    }
    response = stringBuffer.toString();
    System.out.println("full ads response = " + response);
}
catch (Exception ex)
{
    //   ex.printStackTrace();
}
finally
{
    try
    {
        if (conn != null)
        {
            InputStream in1 = (conn).getErrorStream();
            if (in1 != null)
            {
                in1.close();
            }
            conn.getInputStream().close();
            in = null;
            conn.disconnect();
            conn = null;
        }
        if (rd != null)
        {
            rd.close();
            rd = null;
        }
        if (in != null)
        {
            in.close();
            in = null;
        }
    }
    catch (Exception e)
    {
    }
}
return null;        

共有3个答案

翟元凯
2023-03-14

你是在windows还是linux上运行?查看这篇文章,希望能有所帮助:http://edmund.haselwanter.com/en/blog/2009/03/13/tomcat-too-many-open-files/

哈烨熠
2023-03-14

我最近遇到这个问题时,试图使大量的连接到一个无法到达的URL。连接将失败与未知主机异常,但最终失败与java.net.SocketExc农田:打开的文件太多。

问题是,底层本机套接字句柄是由HttpURLConnection创建的。似乎直到对象被垃圾回收后才释放此句柄。在我的例子中,没有足够的内存被用来触发垃圾回收机制。如果GC从不运行,本机句柄就不会释放。

我的解决方案是定期给系统打电话。获取未知hostException时使用gc()。我知道这看起来像是一个乱七八糟的问题,但它成功了,底层的本机句柄被释放,问题消失了。

方光华
2023-03-14

UnknownHostException仅表示您使用的URL引用了不存在的主机名,或者可能是主机名的DNS记录或系统当时处于转换状态。

套接字泄漏可能是由您下面过多的清理代码引起的,请参阅注释。

当你压制所有例外时,你就不希望哈迪斯发现出了什么问题。所以这是首先要解决的问题。永远不要忽视例外。记录他们。打印他们的堆栈痕迹。做某事。

但是,您的代码还有许多其他问题:

HttpURLConnection conn = null;
BufferedReader rd = null;
InputStream in = null;
try
{
    // Send data
    String urlStr = URL;

这个变量是多余的。只需使用下面的URL

    URL url = new URL(urlStr);
    conn = (HttpURLConnection)url.openConnection();
    conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");

好到目前为止。

    int contentLength = conn.getContentLength();
    //   System.out.println("content length 1" +  contentLength);
    if (contentLength <= 0)

检查零内容长度是非常不寻常的。这是检查错误的代理吗?我只想删除这个测试。

    {
        InputStream in1 = (conn).getErrorStream();
        if (in1 != null)
        {
            in1.close();
        }
        conn.getInputStream().close();
        in = null;
        conn.disconnect();
        conn = null;
        return null;
    }

所有这些都是多余的。你已经把它放在最后一个街区了。移除它。

    in = conn.getInputStream();
    if (conn.getResponseCode() != 200)

现在,这就是如何检查错误。但是,在调用getInputStream(),之前,必须调用getResponseCode(),否则后者可能会在您可能对404响应代码更感兴趣时抛出FileNotFoundException

    {
        InputStream in1 = (conn).getErrorStream();
        if (in1 != null)
        {
            in1.close();
        }
        conn.getInputStream().close();
        in = null;
        conn.disconnect();
        conn = null;
        in.close();
        in = null;
        return null;
    }

同样,上述所有内容都是多余的。你已经把它放在最后一个街区了。移除它。

    // Get the response
    rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    StringBuffer stringBuffer = new StringBuffer();
    String line = null;

行的初始化是冗余的。变量在下一行中赋值。移除它。

    while ((line = rd.readLine()) != null)
    {
        stringBuffer.append(line);
    }
    response = stringBuffer.toString();
    System.out.println("full ads response = " + response);
}
catch (Exception ex)

您应该只在此处捕获IOException

{
    //   ex.printStackTrace();

永远不要忽略异常。

}
finally
{
    try
    {
        if (conn != null)
        {
            InputStream in1 = (conn).getErrorStream();
            if (in1 != null)
            {
                in1.close();
            }

您不需要获取或关闭错误流。移除所有这些。

            conn.getInputStream().close();
            in = null;

将此变量设置为null毫无意义。这是一个局部变量,所以无论如何它都会超出范围。

            conn.disconnect();
            conn = null;

同上。

        }
        if (rd != null)
        {
            rd.close();
            rd = null;
        }

您已经关闭了输入流。这是多余的。移除此块。

        if (in != null)
        {
            in.close();
            in = null;
        }

您已经关闭了连接的输入流。这都是多余的。移除它。

    }
    catch (Exception e)
    {
    }

同样,您应该只在这里捕获IOException,而不应该忽略错误。就我个人而言,我会让该方法抛出IOException,而根本没有任何catch块。返回null对调用方不是很有用。一般来说,他最好确切地知道出了什么问题,这样他就可以做出有用的决定,该怎么办。

}
return null;        

 类似资料:
  • 我有一个Hibernate,Spring,Debian,Tomcat,MySql堆栈在Linode服务器上与一些客户端一起生产。它是一个Spring多租户应用程序,为大约30个客户端托管网页。 应用程序开始罚款,然后过了一会儿,我得到这个错误: 但是,在抛出此错误之前,nagios会提醒我对服务器的ping停止响应。 以前,我有nginx作为代理,并得到这个nginx错误每个请求,但不得不重新启动

  • 问题内容: 我使用多个文件来执行一些文件I / O(写入19个文件,确实如此)。写他们几百次后,我得到了。但实际上我一次只能打开几个文件。这里有什么问题?我可以验证写入是否成功。 问题答案: 在Linux和其他UNIX /类似UNIX的平台上,操作系统对进程在任何给定时间可能具有的打开文件描述符的数量进行了限制。在过去,此限制曾经是硬接线1,并且相对较小。如今,它要大得多(几百/千),并且受“软”

  • 我有一个简单的代码,从网络上获取一个XML文件。更具体地说,是一个包含挪威银行汇率的XML文件。问题是,它只是有时起作用。通常,它从来没有工作的第一次。 经过一些测试,我很确定它在上崩溃。但正如一所说,并不是每次都这样。 那么,有没有更好的方法来实现这一点,并确保它正确地获取XML文件 感谢所有的帮助。 } 错误如下: JAVA网SocketException:在java上重置连接。网Socket

  • 我正在编写一个需要读取/写入大量文件的遗传算法。GA的适用性测试是调用一个名为的程序,该程序将文件作为输入并生成文件作为输出。 一切都在工作,除非我使遗传算法的种群规模和/或总代数太大。然后,经过这么多代人,我开始得到这个:(我为许多不同的文件反复得到它,索引 只是我上次运行它时首先出现的那个)。这很奇怪,因为我不是在第一代或第二代之后得到错误,而是在相当多的世代之后,这表明每一代都会打开更多它没

  • 我试图检测是否存在互联网连接,以及是否可以访问网站。我有一个广播接收器,在接收时运行以下方法: 当连接到Wifi且通过互联网应用程序可以访问谷歌时,我发现以下错误: 我错过了什么?

  • 当我通过SOAPUI运行WS时,我会间歇性地遇到以下错误。有时它不工作,然后它继续工作,然后又有时它不工作。另一个问题是,客户机提供的测试web服务运行良好,没有任何问题,但当我们切换到生产服务时,它会给出问题。谷歌搜索并做了一些更改(HttpConfig上的超时,jetty maxIdleTime),但仍然无法使其工作:(有没有办法缩小问题的范围? 只需添加使用SOAPUI与生产endpoint