Java 多线程处理 Socket Too many open files异常
在本地机器上做了一次Java Socket的多线程的实验,server和client在,思路是server和client都想用多线程处理,且socket相重复利用,结果遇到异常。
描述一下及其环境:
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端代码:
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));
}
}
}
Client代码:
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);
}
}
}
刚开始运行没有问题,大概运行25分钟之后会出现入下异常:
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)
各位大佬帮忙看看是哪个地方认识的有误区还是配置问题?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
貌似没看到close或者try with resource
所以应该是socket没关