java.net.SocketException: No buffer space available (maximum connections reached?): connectionTomcat运行一段时间后就报以上错误。是什么原因引起的?跪求

解决方案 »

  1.   


    日志出现这个提示:        信息: ContextListener: attributeAdded('org.apache.jasper.compiler.TldLocationsCache', 'org.apache.jasper.compiler.TldLocationsCache@136d9d8')这是什么意思
      

  2.   

    信息貌似不够,不足以判断具体原因java.net.SocketException: No buffer space available (maximum connections reached?): connection从这里可以看出,当要连接时,发现缓存空间不足,异常提示是否已抵达最多连接数?但也只是存疑而已。
    但缓存空间不足是肯定的。这就需要多方面查原因了
    1.是否连接关闭机制未完善
    2.是否抵达最多连接数
    先确定这两点,后续就好办了
      

  3.   

    这个是上下文环境监听器监听到了 有一个属性被添加了
    属性的key是:'org.apache.jasper.compiler.TldLocationsCache'
    属性的value是:'org.apache.jasper.compiler.TldLocationsCache@136d9d8'
      

  4.   

    代码这样的:读取POST响应的数据会不会有问题
    .....
    public void test(String param){                        URL realUrl = new URL(url);
    HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
    conn.setDoOutput(true);
    conn.setDoInput(true);
    conn.setRequestMethod("POST"); out = new DataOutputStream(conn.getOutputStream());
    out.write(param.getBytes());
    out.flush();
          
                           InputStream is = conn.getInputStream();
                   result = inputStream2String(is);
    }
     
    public static String inputStream2String(InputStream is) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    int i = -1;
    while ((i = is.read()) != -1) {
    baos.write(i);
    }
    return baos.toString();
    }
      

  5.   

    后来加上去了,但我看网上说 inputString.close后 那个connect就自己关闭了啊
      

  6.   

    http://blog.sina.com.cn/s/blog_56beadc60100j9zu.html
      

  7.   

    额,现在我换了一个Tomcat,之前的情况是我在一台服务器上开了2个Tomcat,出问题的是那个7.0解压的版本,还有一个是安装版的6.0,现在我把这个服务器放到6.0下面,暂时没有出现问题。
    程序里面做的修改是 1: 增加conn.disconnect  (虽然我在网上看了有人说只要把InputString关掉,连接就关掉了 http://blog.sina.com.cn/s/blog_56beadc60100j9zu.html
    2:修改读流的方法,好像这个会阻塞
     while ((i = is.read()) != -1) {
                baos.write(i);
            }
     
    //改为先读出HTTP流长度,然后ReadFully全部读出来。。 不知道还会不会出现问题
      

  8.   

    回12楼:
    一般来说只有是大的关闭了才会连带小的一起关闭,比如这里的connection关闭了,可能会连带关闭于其上打开的inputstream,当然保险起见,都关闭。多压力测试测试,看看还会不会有问题。
      

  9.   

    今天又出现了,我要抓狂啦java.net.SocketException: No buffer space available (maximum connections reached?): connect
    java.net.SocketException: No buffer space available (maximum connections reached?): connect
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(Unknown Source)
    at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
    at java.net.PlainSocketImpl.connect(Unknown Source)
    at java.net.SocksSocketImpl.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at sun.net.NetworkClient.doConnect(Unknown Source)
    at sun.net.www.http.HttpClient.openServer(Unknown Source)
    at sun.net.www.http.HttpClient.openServer(Unknown Source)
    at sun.net.www.http.HttpClient.<init>(Unknown Source)
    at sun.net.www.http.HttpClient.New(Unknown Source)
    at sun.net.www.http.HttpClient.New(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
    at cn.eden.test.Test.sendPost(Test.java:150)
    at cn.eden.test.Test.doGet(Test.java:58)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Unknown Source)
      

  10.   


     这是出错时后 netstat -an的情况
      

  11.   

    如果这个netstat反映出来的是真实连接数,那就有理由怀疑是单个连接占用的buffer过多导致的No buffer space available问题,试试用JProfiler之类的软件来监控查实一下。
      

  12.   


    这是代码,有问题吗?public class Test extends HttpServlet { private static final String userName = "test";
    private static final String pwd = "test";
    private static final String channelCode = "123456";
    private static final String insertType = "00";
    private static final String url1 = "http://gmotabeta.g188.net/channelsys/validateInsert"; private static final String url2 = "http://gmotabeta.g188.net/channelsys/packageValidate";
    private static final String success = "000000"; 
    private static final long serialVersionUID = 1L; /**
     * @see HttpServlet#HttpServlet()
     */
    public Test() {
    super();
    } /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doGet(HttpServletRequest request,
    HttpServletResponse response) throws ServletException, IOException {
    String packageId = request.getParameter("packageId");
    System.out.println("接收到的ID:" + packageId);
    if (packageId != null) {
    String param = postParam(userName, pwd, channelCode, insertType);
    String s1 = sendPost(url1, param);
    System.out.println("接收:" + s1); String status = getValue(s1, "status");
    String tokenPwd = getValue(s1, "tokenPwd"); System.out.println("status: " + status);
    System.out.println("tokenPwd: " + tokenPwd); if (success.equals(status)) {
    System.out.println("成功!"); response.sendRedirect(url2 + "?" + "channelcode=" + channelCode
    + "&tokenPwd=" + tokenPwd + "&packageId=" + packageId);// 重定向
    // response.sendRedirect("http://123.125.169.251:8080/testweb2/");
    } else if (status == null) {
    response.setStatus(403);
    System.out.println("status为空异常");
    } else {
    System.out.println("失败!");
    response.sendRedirect("http://221.130.10.212:8080/cmccwap/1.wml");
    }
    } else {
    response.setStatus(404);
    System.out.println("非法请求");
    }
    } /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doPost(HttpServletRequest request,
    HttpServletResponse response) throws ServletException, IOException { } public static String sendPost(String url, String param) {

    DataOutputStream out = null;
    HttpURLConnection conn = null;
    DataInputStream is = null;
    String result = "";
    try {
    URL realUrl = new URL(url);
    conn = (HttpURLConnection) realUrl.openConnection();
    conn.setDoOutput(true);
    conn.setDoInput(true);
    conn.setRequestMethod("POST");

    out = new DataOutputStream(conn.getOutputStream());
    out.write(param.getBytes());
    out.flush();
    int lenght = conn.getContentLength();
    byte[] buf = new byte[lenght];
    is = new DataInputStream(conn.getInputStream());

    is.readFully(buf);
    String tmp = new String(buf);
    System.out.println("读取字符串:"+ tmp);
    result = tmp;

    } catch (Exception e) {
    System.out.println("POST请求异常" + e);
    e.printStackTrace();
    } finally {
    try {
    if (is != null) {
    System.out.println("关闭inputStream");
    is.close();
    }
    if (out != null) {
    System.out.println("关闭DataOutputStream");
    out.close();
    }
    conn.disconnect();
    } catch (IOException ex) {
    ex.printStackTrace();
    }
    }
    return result;
    } public static String inputStream2String(InputStream is) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    int i = -1;
    while ((i = is.read()) != -1) {
    baos.write(i);
    }
    return baos.toString();
    } public static String postParam(String userName, String pwd,
    String channelCode, String insertType) {
    String request = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "\n"
    + "<request>" + "\n" + "<userName>" + userName + "</userName>"
    + "\n" + "<pwd>" + pwd + "</pwd>" + "\n" + "<channelCode>"
    + channelCode + "</channelCode>" + "\n" + "<insertType>"
    + insertType + "</insertType>" + "\n" + "</request>"; return request;
    } public static String getValue(String str, String keyWord) {
    String start = "<" + keyWord + ">";
    String end = "</" + keyWord + ">";
    String value = null; try {
    value = str.substring(str.indexOf(start) + start.length());
    value = value.substring(0, value.indexOf(end));
    } catch (Exception e) {
    e.printStackTrace();
    }
    return value;
    }}
      

  13.   

    简化,除去不必要的,留下最精简的却又能暴露出问题的代码,看只有两个Socket连接就报异常了,异常应该不难出来吧?
      

  14.   

    出异常的地方在这个 发送Post请求的方法里,我实在找不到哪不对劲啊  public static String sendPost(String url, String param) {
            
            DataOutputStream out = null;
            HttpURLConnection conn = null;
            DataInputStream is = null;
            String result = "";
            try {
                URL realUrl = new URL(url);
                conn = (HttpURLConnection) realUrl.openConnection();
                conn.setDoOutput(true);
                conn.setDoInput(true);
                conn.setRequestMethod("POST");
                
                out = new DataOutputStream(conn.getOutputStream()); //在这里
                out.write(param.getBytes());
                out.flush();            
                int lenght = conn.getContentLength();
                byte[] buf = new byte[lenght];
                is = new DataInputStream(conn.getInputStream());
                
                is.readFully(buf);
                String tmp = new String(buf);
                System.out.println("读取字符串:"+ tmp);
                result = tmp;
                
            } catch (Exception e) {
                System.out.println("POST请求异常" + e);
                e.printStackTrace();
            } finally {
                try {
                    if (is != null) {
                        System.out.println("关闭inputStream");
                        is.close();
                    }
                    if (out != null) {
                        System.out.println("关闭DataOutputStream");
                        out.close();
                    }
                    conn.disconnect();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            return result;
        }
      

  15.   

    没有设置超时?conn.setConnectTimeout(30000); //连接超时
    conn.setReadTimeout(30000);