Java套接字服务器提供java.net.SocketException:没有可用的缓冲区空间(达到最大连接数?):连接异常

时间:2014-12-10 12:27:16

标签: java tcp socketserver

我在客户端创建了客户端服务器应用程序,当我向服务器发送多个请求一段时间后,它给出了以下错误。当我监视TCPview时,CLOSE_WAIT状态上有很多端口连接。有任何人遇到这样的issue.Please找到下面的错误日志

 java.net.SocketException: No buffer space available (maximum connections reached?): connect
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
    at java.net.Socket.connect(Socket.java:529)
    at java.net.Socket.connect(Socket.java:478)
    at java.net.Socket.<init>(Socket.java:375)
    at java.net.Socket.<init>(Socket.java:189)
    at com.lk.cc.socketserver.Main.isHostRunning(Main.java:90)
    at com.lk.cc.socketserver.Main.main(Main.java:43)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
    Exception in thread "main" java.lang.NullPointerException
        at com.lk.cc.socketserver.Main.isHostRunning(Main.java:102)
        at com.lk.cc.socketserver.Main.main(Main.java:43)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

服务器主机类

public class ServerHost extends Thread {

  private ServerSocket serverSocket;

      public ServerHost(int port) throws IOException {
        serverSocket = new ServerSocket(port);

      }

      public void run() throws IOException{
        while (true) {
          Socket server = null;
          DataInputStream in = null;
          DataOutputStream out = null;
          try {
            System.out.println("Host 1 Established .. ");
            System.out.println("Waiting for client on port " +
                               serverSocket.getLocalPort() + "...");
            server = serverSocket.accept();
            System.out.println("Just connected to "
                               + server.getRemoteSocketAddress());
            in =
                new DataInputStream(server.getInputStream());

            if (in.available() > 0) {
              System.out.println("Recieved client message  :" + in.readUTF());

              out =  new DataOutputStream(server.getOutputStream());

              // send recieved response from host X to client

              out.writeUTF("Response from Host 1 " + server.getLocalSocketAddress() + " \nGoodbye!");

              System.out.println("client socket isClosed()    " + server.isClosed());
            }
          } catch (SocketTimeoutException s) {
            System.out.println("Socket timed out!");
            // break;
          } catch (IOException e) {
            e.printStackTrace();
            // break;
          } finally {
            if (out != null) {
              try {
                out.flush();
              } catch (IOException e) {
                e.printStackTrace();
              }
            }
            if (out != null) {
              try {
                out.close();
              } catch (IOException e) {
                e.printStackTrace();
              }
            }
            if (in != null) {
              try {
                in.close();
              } catch (IOException e) {
                e.printStackTrace();
              }
            }

            if (server != null) {
              try {
                server.close();
              } catch (IOException e) {
                e.printStackTrace();
              }
            }
          }
        }
      }

      public static void main(String[] args) {
        int port = 7881;
        try {
          Thread t = new ServerHost(port);
          t.start();
        } catch (IOException e) {
          e.printStackTrace();
      }
   }
}

客户

    public class Main {

  private static ArrayList<HostConnections> hostList;


  public static void init() {
    hostList = new ArrayList<HostConnections>();
    hostList.add(new HostConnections("localhost", 7881));
    hostList.add(new HostConnections("localhost", 7882));
    hostList.add(new HostConnections("localhost", 7883));
    hostList.add(new HostConnections("localhost", 7884));
  }

  public static void main(String[] args) {
    // write your code here
    boolean hostStatus=true;
    init();
    while (hostStatus) {
      System.out.println("Used " + hostList.get(0));
      HostConnections nextHost = hostList.get(0);
      //Collections.rotate(hostList, -1);
      System.out.println(hostList);

      hostStatus = isHostRunning(nextHost);
      System.out.println(hostStatus);
    }
  }


  private static boolean isHostRunning(HostConnections availableHost) {
    boolean isAlive = false;
    Socket client=null;
    try {
        client = new Socket(availableHost.getHostIpAddress(), availableHost.getHostPort());
      //client.getInputStream().close();

     // client.getOutputStream().close();
      isAlive = true;

    } catch ( Exception e) {
      e.printStackTrace();

    }finally {
      try {
        //client.getOutputStream().flush();
        client.close();
        client.isClosed();
        System.out.println(client.isClosed());
      } catch (IOException e) {
        e.printStackTrace();
      }
    }

    return isAlive;
  }
}

我的要求是检查列表中的所有连接是否每次都可用。 谢谢

1 个答案:

答案 0 :(得分:1)

你在某个地方漏掉了插座。 CLOSE_WAIT表示TCP已收到对等方的关闭,正在等待本地应用程序关闭套接字。

您还应该在该测试循环中尝试睡眠。你就像没有明天那样烧掉插座。

事实上,我质疑整个目的。了解任何资源是否可用的唯一可靠方法是尝试使用它并处理正常执行过程中出现的错误。其他任何东西都等于算命。

NB:

  1. flush()之前close()是多余的。
  2. 拨打isClosed()available()通常是浪费时间,这也不例外。
  3. 您是否知道此代码仅测试一个主机?