Java multithreading handles Socket Too many open files exceptions

A multithreading experiment of Java Socket is done on the local machine, server and client are in, the idea is that both server and client want to use multithreading, and socket is reused, and an exception is encountered.
describe and its environment:
3.1 GHz Intel Core i7
16 GB 1867 MHz DDR3,

  Client git:(2.0-SNAPSHOT)  ulimit -a                                                       
-t: cpu time (seconds)              unlimited
-f: file size (blocks)              unlimited
-d: data seg size (kbytes)          unlimited
-s: stack size (kbytes)             8192
-c: core file size (blocks)         0
-v: address space (kbytes)          unlimited
-l: locked-in-memory size (kbytes)  unlimited
-u: processes                       2128
-n: file descriptors                1048600
  Client git:(2.0-SNAPSHOT)  sysctl net.inet.ip.portrange                                    
net.inet.ip.portrange.lowfirst: 1023
net.inet.ip.portrange.lowlast: 600
net.inet.ip.portrange.first: 1024
net.inet.ip.portrange.last: 65535
net.inet.ip.portrange.hifirst: 49152
net.inet.ip.portrange.hilast: 65535
  Client git:(2.0-SNAPSHOT)  

Server side code:

public class EchoServer {

    public static ExecutorService executorService;
    public static final String NEWLINE = "\r\n";
    public static long COUNT = 0;

    public EchoServer(int port) throws IOException {
        ServerSocket serverSocket = new ServerSocket();
        serverSocket.bind(new InetSocketAddress("127.0.0.1", port));
        System.out.println("Starting echo server on port: " + port);
        while (true) {
            long start = System.currentTimeMillis();
            COUNTPP;
            Socket socket = serverSocket.accept();
            ProcessTask processTask = new ProcessTask(socket, start);
            executorService.execute(processTask);
        }
    }

    public static void main(String[] args) throws IOException {
        executorService = Executors.newFixedThreadPool(5 * Runtime.getRuntime().availableProcessors());
        new EchoServer(9999);
    }

    public static class ProcessTask implements Runnable {

        private Socket socket;
        private long startTime;

        public ProcessTask(Socket socket, long startTime) {
            this.socket = socket;
            this.startTime = startTime;
        }

        public void run() {
            BufferedReader br = null;
            PrintWriter out = null;

            try {
                br = getReader(socket);
                out = getWriter(socket);

                String msg;
                while ((msg = br.readLine()) != null) {

                    String res = "Server Reply : " + msg;
                    out.println(res);
                    out.flush();
                }
                long end = System.currentTimeMillis();
                System.out.println("Closing connection with client.  : " + ((end - startTime)));
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    socket.shutdownInput();
                    socket.shutdownOutput();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        private PrintWriter getWriter(Socket socket) throws IOException {
            OutputStream socketOut = socket.getOutputStream();
            return new PrintWriter(socketOut, true);
        }

        private BufferedReader getReader(Socket socket) throws IOException {
            InputStream socketIn = socket.getInputStream();
            return new BufferedReader(new InputStreamReader(socketIn));
        }
    }
}

Client Code:

public class EchoClient {

    public static final int port = 9999;
    public static final String NEWLINE = "\r\n";
    public static final long NANOSECONDS_PER_SECOND = 1000 * 1000 * 1000;
    public static final long REQUESTS_PER_SECOND    = 1000 * 1000;

    public static long COUNT = 0;

    public static void main(String args[]) {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                50, 50, 3000L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>());

        List<Task> tasks = new ArrayList<>();

        for (int i = 0; i < 10000; iPP) {
            tasks.add(new Task(i, port));
        }

        boolean flag = false;
        while (true) {
            tasks.stream().forEach(
                    task ->
                    {
                        threadPoolExecutor.submit(task);
                        COUNTPP;
                        try {
                            long sleep_time = NANOSECONDS_PER_SECOND / REQUESTS_PER_SECOND;
                            TimeUnit.NANOSECONDS.sleep(sleep_time);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
            );
            if (flag) {
                break;
            }
        }

        threadPoolExecutor.shutdown();
    }

    public static class Task implements Callable<Long> {

        private int port;
        private int id;
        private String taskName;

        public Task(int id, int port) {
            this.id = id;
            this.port = port;
            this.taskName = "Client_" + this.id;
        }

        public Long call() {
            long start = -1;
            long end = -1;
            try {
                Socket socket = new Socket("127.0.0.1", port);
                start = System.currentTimeMillis();
                String msg = "From " + taskName;
                msg = msg + NEWLINE;
                for (int i = 1; i <= 1; iPP) {
                    OutputStream socketOut = null;
                    BufferedReader br = null;
                    try {
                        socketOut = socket.getOutputStream();
                        socketOut.write(msg.getBytes());
                        socketOut.flush();

                        br = new BufferedReader(new InputStreamReader(
                                socket.getInputStream()));
                        String res = br.readLine();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        socket.shutdownInput();
                        socket.shutdownOutput();
                    }
                }
                end = System.currentTimeMillis();

                System.out.println(taskName + " !" + "  : " + ((end - start)));
            } catch (IOException e) {
                e.printStackTrace();
            }
            return (end - start);
        }
    }
}

there is no problem at the beginning of the operation, but an input exception will occur after about 25 minutes of running:

java.net.SocketException: Too many open files
    at java.net.Socket.createImpl(Socket.java:460)
    at java.net.Socket.<init>(Socket.java:431)
    at java.net.Socket.<init>(Socket.java:211)
    at com.study.base.EchoClient$Task.call(EchoClient.java:68)
    at com.study.base.EchoClient$Task.call(EchoClient.java:52)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

can you help me to see if there is a misunderstanding or a configuration problem?


doesn't seem to see close or try with resource
, so it should be socket.

Menu