栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java16 Unix Domain socket他来了

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java16 Unix Domain socket他来了

Unix Domain socket

A UNIX socket is an inter-process communication mechanism that allows bidirectional data exchange between processes running on the same machine.

他在socket的框架上发展出一种IPC(inter-process communication)机制。对于本地的进程间通信,Unix Domain socket 比TCP / IP环回连接更安全,更有效。

Unix Domain socket的场景

本机进程通信一直是一个大的需求。例如交互式的命令里,只是想获取一些数据,很多时候没必要开启额外的端口。开启端口就会有开多少的问题,机器上的随机端口很可能占用了你设置的值。进程启动先查哪些端口有没有被占用,查完之后再命令行等形式启动起来。最后client还得记住对应的端口。jdk本身实现命令的时候就没有这么麻烦,例如jstack等,用的都是 Domain socket。他们约定了一个固定的文件位置 /tmp/.java_pid${ns_pid}。java在jdk16之前没有Unix Domain socket,如果想用的话,得自己写jni。

目前这个功能已经完成,支持的平台如下。

Unix-domain sockets have long been a feature of most Unix platforms, and are now supported in Windows 10 and Windows Server 2019.

我们的理解就是对windows有一定的要求。

code

我们编写代码和以前区别不大。主要是围绕SocketChannel 和 ServerSocketChannel。在原来绑定ip和地址的地方换成UnixDomainSocketAddress。Channel open的时候选择好域,这个域还是枚举,StandardProtocolFamily。
我们看看ServerSocketChannel的code

 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(StandardProtocolFamily.UNIX);
 UnixDomainSocketAddress of = UnixDomainSocketAddress.of("./test.sock");
 serverSocketChannel.bind(of);
 while (true) {
     SocketChannel socketChannel = serverSocketChannel.accept();
     ByteBuffer buf = ByteBuffer.allocate(48);
     int bytesRead = socketChannel.read(buf);
     while (bytesRead > 0) {
  buf.flip();
  while (buf.hasRemaining()) {
      System.out.print((char) buf.get());
  }
  System.out.println();
  buf.clear();
  bytesRead = socketChannel.read(buf);
     }
 }

读取的代码和以前是一样的。SocketChannel的部分也一样。

 SocketChannel socketChannel = SocketChannel.open(StandardProtocolFamily.UNIX);
 UnixDomainSocketAddress of = UnixDomainSocketAddress.of("./test.sock");
 boolean connect = socketChannel.connect(of);
 String newData = "this is domain socket..." + System.currentTimeMillis();
 ByteBuffer buf = ByteBuffer.allocate(48);
 buf.clear();
 buf.put(newData.getBytes());

 buf.flip();

 while (buf.hasRemaining()) {
     socketChannel.write(buf);
 }
 socketChannel.close();

jdk选择jdk16,否则编译不过去。下载地址[jdk16 ea]jdk.java.net/16/
我选择绑定文件为当前目录下的test.sock。为什么会绑定文件,可以了解一下socket的发展。

srwxr-xr-x  1 xie  staff     0B 12 27 12:19 test.sock

我们可以看到运行完程序之后产生了一个test.sock,他是s开头的表示他是一个socket文件。建议这个目录写到/tmp下去,后面可以依靠系统清理,否则就要自己去清理这个文件了。

demo代码的位置[domain socket demo]github.com/xpbob/java/tree/main/domainsocket

总结

Unix Domain socket给java同机进程通信带来了很大的方便。例如开发一些特殊的功能,完全可以做成本机通信,需要有权限的人员ssh到具体机器操作。开发起来也很方便,只不过socket文件需要自己去做管理。

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号