我正在
java.net.SocketException: Too many open files.
我的代码:
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();
COUNT++;
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));
}
}
}
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; i++) {
tasks.add(new Task(i, port));
}
boolean flag = false;
while (true) {
tasks.stream().forEach(
task ->
{
threadPoolExecutor.submit(task);
COUNT++;
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; i++) {
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);
}
}
}
➜ 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) ✗
答案 0 :(得分:1)
您正在泄漏FD,因为您永远不会关闭已接受的套接字,也不会关闭已连接的套接字。你关闭它们,但如果你关闭它们既不充分也不必要。