junixsocket server report “too many files open“

Environment:

  • OS: [mac os] Version [11.4]
  • java version “1.8.0_131”
  • junixsocket version 2.4.0

初步怀疑可能是关闭文件描述符的时候存在问题

该问题已经在最新版本2.5.0中修复

1、在server端每次调用accept()方法时,程序的文件描述符列表都会增加一个none的文件描述符。并且在调用close方法后,这个文件描述符没有被关闭。
在这里插入图片描述

2、查看调用accept()方法
图片: https://cooper.didichuxing.com/cooper_gateway/cn/shimo-images/JGs0IzvBY2sseuid/image.png
在代码执行到标记1的时候创建了一个空的文件描述符81
在代码执行到标记2的时候创建了一个指向/tmp/junixsocket-test.socket的文件描述符82
在这里插入图片描述
大致可以断定在标记2执行的时候没有关闭标记1中创建的文件描述符
接下来详细看标记2中的代码执行逻辑
在这里插入图片描述
①、上图中红色圈出的就是在标记1中创建的空文件描述符
②、在java代码中并没有显式的看到哪里释放了空的文件描述符,不知道在NATIVE方法中是否存在释放的逻辑。需要进一步看Native部分的逻辑实现…

代码部分

client端代码

/**
 * A simple demo client.
 * 
 * @author Christian Kohlschütter
 * @see UDSServer
 */
public class UDSClient {
  final static String udsPath = "/tmp/junixsocket-test.sock";
  public static void main(String[] args) throws IOException {

    final File socketFile = new File(udsPath);

    long start = System.currentTimeMillis();
    test2(socketFile);

    long end = System.currentTimeMillis();

    System.out.println("total = " + (end - start));
  }

  private static void test2(File socketFile) throws SocketException {
    for (int i = 0; i < 100000; i++) {
      FactoryArg factoryArg = new FactoryArg(udsPath);
      Socket sock = null;
      try {
        sock = factoryArg.createSocket();
        try {
          sock.connect(new InetSocketAddress("localhost", 1000));
        } catch (SocketException e) {
          System.out.println("Cannot connect to server. Have you started it?");
          System.out.println();
          throw e;
        }
        System.out.println("Connected");

        SocketUtil.clientHandle(sock);
      } catch (Exception e) {
        e.printStackTrace();
        System.out.println("i = " + i);
        break;
      } finally {
        try {
          sock.close();
        } catch (IOException e) {
          e.printStackTrace();
        } finally {
          System.out.println("client socket has closed!");
        }

      }
    }
  }

  private static void test1(File socketFile) {
    for (int i = 0; i < 100000; i++) {
      try (AFUNIXSocket sock = AFUNIXSocket.newInstance()) {
        try {
          sock.connect(AFUNIXSocketAddress.of(socketFile));
        } catch (SocketException e) {
          System.out.println("Cannot connect to server. Have you started it?");
          System.out.println();
          throw e;
        }
        System.out.println("Connected");

        SocketUtil.clientHandle(sock);
      } catch (Exception e) {
        e.printStackTrace();
        System.out.println("i = " + i);
        break;
      }
    }
  }

  //100000 -> 695857
  // 100000 1k -> 154671
  
}

server端代码

/**
 * A simple demo server.
 * 
 * @author Christian Kohlschütter
 * @see UDSClient
 */
public final class UDSServer {


  private UDSServer() {
    throw new UnsupportedOperationException("No instances");
  }

  public static void main(String[] args) throws IOException {
    final File socketFile = new File("/tmp/junixsocket-test.sock");
    System.out.println(socketFile);
    AFUNIXServerSocket server = null;
    try {
      server = AFUNIXServerSocket.newInstance();
//      server.setReuseAddress(true);
      server.bind(AFUNIXSocketAddress.of(socketFile));
      System.out.println("server: " + server);

      while (!Thread.interrupted()) {
        System.out.println("Waiting for connection...");
        AFUNIXSocket sock = null;
        try {
          sock = server.accept();
          System.out.println("Connected: " + sock);

          SocketUtil.serverhandle(sock);
        } catch (IOException e) {
          if (server.isClosed()) {
            throw e;
          } else {
            e.printStackTrace();
          }
        }finally {
          if (sock != null) {
            sock.close();
          }
        }
      }
    }finally {
      if (server != null) {
        server.close();
      }
    }
  }


}

SocketUtil代码

/**
 * @author keweizhang
 * @Description
 * @create 2022-06-09 11:19
 */
public class SocketUtil {
  private static final int MAX_NUMBER = 5;
  private static String oneKBString = null;

  public static void serverhandle(Socket sock) throws IOException {
    InputStream is = null;
    OutputStream os = null;
    try {
      os = sock.getOutputStream();
      is = sock.getInputStream();
      os.write("Hello, dear Client".getBytes("UTF-8"));
      os.flush();

      byte[] buf = new byte[128];
      int read = is.read(buf);
      System.out.println("Client's response: " + new String(buf, 0, read, "UTF-8"));
    } finally {
      if (is != null) {
        is.close();
      }
      if (os != null) {
        os.close();
      }
    }
  }


  public static void clientHandle(Socket sock) throws IOException {
    InputStream is = null;
    OutputStream os = null;
    try {
      is = sock.getInputStream();
      os = sock.getOutputStream();
      TimeUnit.MILLISECONDS.sleep(1);

      os.write(getOneKB().getBytes("UTF-8"));
      os.flush();

      byte[] buf = new byte[128];
      int read = is.read(buf);
      System.out.println("Server says: " + new String(buf, 0, read, "UTF-8"));


    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (is != null) {
        is.close();
      }
      if (os != null) {
        os.close();
      }
    }
  }

  public static String getOneKB() {
    if (oneKBString == null) {
      StringBuffer stringBuffer = new StringBuffer();
      for (int i = 0; i < 1024; i++) {
        stringBuffer.append("A");
      }
      stringBuffer.append("\n");
      oneKBString = stringBuffer.toString();
    }
    return oneKBString;
  }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值