乐趣区

关于java:网络协议之socket协议详解之Unix-domain-Socket

简介

之前的文章咱们讲到了 Socket 中的 Stream Socket 和 Datagram Socket,这两种 Socket 通常别离是基于 tcp 和 udp 协定来进行数据的传输。这两种 Socket 都有一个独特的特点,那就是须要一个 IP 地址和端口来建设客户端和服务器端的连贯。

那么明天咱们会来解说一个非凡的 socket,这个 socket 不须要应用传统的 IP 地址和端口,而是应用文件系统来进行程序之间的数据交互,并且这样的 socket 只能应用在 unix 零碎上。这样的 socket 就是明天咱们要解说的 Unix domain Socket。

什么是 Unix domain Socket

什么是 Unix domain Socket 呢?咱们从名字就可以看进去,这个 Socket 是和 unix domain 有关系的,也就是说这个 socket 须要用到 unix 上面的一些非凡性能。

咱们思考下罕用的 windows 零碎和 unix 零碎,他们最大的区别在哪里呢?

其实最大的区别就是 unix 操作系统中所有都能够看做是文件,包含程序运行的一些信息。

那么咱们是不是能够间接借助于这些程序运行时产生的文件来进行不同程序之间数据的交互呢?答案是必定的。这就是咱们明天要探讨的 Unix domain Socket。

Unix domain Socket 能够简称为 UDS,不同程序间的数据能够在操作系统层,借助于文件系统来进行数据交换。

对于程序自身来说,只须要读取和写入共享的 socket 文件即可,也就是说不同的程序之间通过 socket 文件来进行数据交互。

和基于 IP 和端口的 Socket 一样,Unix domain Socket 也能够分为 Stream Socket 和 Datagram Socket。

咱们最多看到 Unix domain socket 的中央可能就是 docker 了,作为一种容器技术,docker 须要和实体机进行疾速的数据传输和信息替换,个别状况下 UDS 的文件是以.socket 结尾的,咱们能够在 /var/run 目录上面应用上面的命令来查找:

find . -name "*.sock"

如果你有 docker 在运行的话,能够失去上面的后果:

./docker.sock
./docker/libnetwork/6d66a24bfbbfa231a668da4f1ed543844a0514e4db3a1f7d8001a04a817b91fb.sock
./docker/libcontainerd/docker-containerd.sock

能够看到 docker 是通过下面的 3 个 sock 文件来进行通信的。

应用 socat 来创立 Unix Domain Sockets

之前提到了 socat 这个万能的工具,不仅能够创立 tcp 的监听服务器,还能创立 udp 的监听服务器,当然对于 UDS 来说也不在话下。咱们来看下应用 socat 来创立 UDS 服务器所须要用到的参数:

      unix-listen:<filename>    groups=FD,SOCKET,NAMED,LISTEN,CHILD,RETRY,UNIX
      unix-recvfrom:<filename>  groups=FD,SOCKET,NAMED,CHILD,RETRY,UNIX

这里咱们要应用到 unix-listen 和 unix-recvfrom 这两个参数,unix-listen 示意的是创立 stream-based UDS 服务,而 unix-recvfrom 示意的是创立 datagram-based UDS。

能够看到两个参数前面都须要传入一个文件名,示意 UDS socket 的地址。

咱们能够这样应用:

socat unix-listen:/tmp/stream.sock,fork /dev/null&
socat unix-recvfrom:/tmp/datagram.sock,fork /dev/null&

这里咱们应用 /tmp/datagram.sock 来示意这个 socket 信息。

其中 fork 参数示意程序在接管到程序包之后持续运行,如果不必 fork,那么程序会主动退出。

socat 前面原本要接一个 bi-address,这里咱们应用 /dev/null,示意抛弃掉所有的 income 信息。

运行后咱们可能失去上面的后果:

[1] 27442
[2] 27450

示意程序曾经胜利执行了,返回的是程序的 pid。

应用 ss 命令来查看 Unix domain Socket

在应用 ss 命令之前,咱们先来看下应用 socat 生成的两个文件:

srwxrwxr-x   1 flydean flydean    0 Mar  2 21:58 stream.sock
srwxrwxr-x   1 flydean flydean    0 Mar  2 21:59 datagram.sock

能够看到这两个文件的权限,rwx 大家都懂,别离是 read,write 和执行权限。那么最后面的 s 是什么呢?

最后面的一位示意的是文件类型,s 示意的就是 socket 文件。

扩大一下,这个地位还能够有其余几种选项:p、d、l、s、c、b 和 -:

其中 p 示意命名管道文件,d 示意目录文件,l 示意符号连贯文件,- 示意一般文件,s 示意 socket 文件,c 示意字符设施文件,b 示意块设施文件。

接下来咱们应用 ss 命令来查看一下之前建设的 UDS 服务。

这里须要应用到上面几个参数:

   -n, --numeric       don't resolve service names
   -l, --listening     display listening sockets
   -x, --unix          display only Unix domain sockets

这里咱们须要应用到下面 3 个选项,x 示意的是显示 UDS,因为是监听,所以应用 - l 参数,最初咱们心愿看到具体的数字,而不是被解析成了服务名,所以这里应用 - n 参数。

咱们能够尝试执行一下上面的命令:

ss -xln

输入会很多,咱们能够 grep 咱们须要的 socket 如下所示:

ss -xln | grep tmp
u_str  LISTEN     0      5      /tmp/stream.sock 11881005              * 0                  
u_dgr  UNCONN     0      0      /tmp/datagram.sock 11882190              * 0  

u_str 示意的是 UDS stream socket,而 u_dg 示意的是 UDS datagram socket。

咱们能够应用 stat 命令来查看 socket 文件的具体信息:

stat /tmp/stream.sock /tmp/datagram.sock
  File:‘/tmp/stream.sock’Size: 0               Blocks: 0          IO Block: 4096   socket
Device: fd02h/64770d    Inode: 134386049   Links: 1
Access: (0775/srwxrwxr-x)  Uid: (1002/    flydean)   Gid: (1002/    flydean)
Access: 2022-03-01 22:33:21.533000000 +0800
Modify: 2022-03-01 22:33:21.533000000 +0800
Change: 2022-03-01 22:33:21.533000000 +0800
 Birth: -
  File:‘/tmp/datagram.sock’Size: 0               Blocks: 0          IO Block: 4096   socket
Device: fd02h/64770d    Inode: 134386050   Links: 1
Access: (0775/srwxrwxr-x)  Uid: (1002/    flydean)   Gid: (1002/    flydean)
Access: 2022-03-01 22:33:22.306000000 +0800
Modify: 2022-03-01 22:33:22.306000000 +0800
Change: 2022-03-01 22:33:22.306000000 +0800
 Birth: -

应用 nc 连贯到 Unix domain Socket 服务

nc 是一个十分弱小的工具,除了能够进行 TCP,UDP 连贯之外,还能够进行 UDS 的连贯,咱们须要应用到上面的参数:

  -U, --unixsock             Use Unix domain sockets only
  -u, --udp                  Use UDP instead of default TCP
  -z                         Zero-I/O mode, report connection status only

- U 示意连贯的是一个 unixsocket。- u 示意是一个 UDP 连贯。

默认状况下 nc 应用的是 TCP 连贯,所以不须要额定的参数。

另外咱们间接建设连贯,并不发送任何数据,所以这里应用 - z 参数。

先连贯 Stream UDS 看看:

nc -U -z /tmp/stream.sock

如果没有输入任何异样数据,阐明连贯胜利了。

而后再连贯 Datagram UDS 看看:

nc -uU -z /tmp/datagram.sock

同样的,如果没有任何异样数据,阐明 Socket 连贯胜利了。

总结

在本章咱们具体介绍了 Unix Domain Socket 的含意,并且应用了 unix 中的一些工具实现了 UDS 的建设,检测和连贯。基本上形容了 UDS 的应用状况。

本文已收录于 http://www.flydean.com/17-unix-domain-socket/

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

欢送关注我的公众号:「程序那些事」, 懂技术,更懂你!

退出移动版