简介

之前的文章我们讲到了Socket中的Stream Socket和Datagram Socket,和有连接的Stream Socket不同,Datagram Socket是无连接的。有连接的Stream Socket表明这个socket是稳定可靠的,所以我们可以在Stream socket中进行稳定的数据传输,当然这个稳定是说数据包不会丢失,但是并不一定能够确保数据包不被篡改。

Datagram Socket这种无连接的通常被用在容许数据部分丢失的场景,比如语音、视频等等,无连接的好处就是不需要TCP那样复杂的建立连接的步骤,所以相对而言更加简单。

Datagram Socket通常使用的就是UDP协议作为底层的数据传输协议。

对于UDP来说,因为UDP协议本身并不会保证数据的顺序和数据异常的处理,这些都需要在应用程序中自己实现。

这两种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,UNIXunix-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.sockFile: ‘/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 +0800Birth: -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 +0800Birth: -

使用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的使用情况。

网络协议之socket协议详解之Unix domain Socket相关推荐

  1. 网络协议之:socket协议详解之Unix domain Socket

    文章目录 简介 什么是Unix domain Socket 使用socat来创建Unix Domain Sockets 使用ss命令来查看Unix domain Socket 使用nc连接到Unix ...

  2. socket技术详解(看清socket编程)

    socket编程是网络常用的编程,我们通过在网络中创建socket关键字来实现网络间的通信,通过收集大量的资料,通过这一章节,充分的了解socket编程,文章用引用了大量大神的分析,加上自己的理解,做 ...

  3. unix网络编程之UNIX Domain Socket IPC (sockaddr_un )

    socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket.虽然网络socket也可用于同一台主机的进程间通讯(通过loop ...

  4. IPC编程C语言,4. UNIX Domain Socket IPC

    4. UNIX Domain Socket IPC socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket.虽然网络so ...

  5. linux ipc通信,linux-IPC进程通信-UNIX Domain Socket IPC (sockaddr_un) (上)

    2011-05-11 15:28 7387人阅读 评论(1) 收藏 分类: C/C++(22) socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制(IPC:即 ...

  6. Unix/Linux编程:Unix domain socket

    UNIX domain socket用于同一主机系统上的相互通信 UNIX domain socket 地址:struct sockaddr_un 在Unix domain中,socket地址以路径名 ...

  7. ARP协议及ARP欺骗详解

    ARP协议及ARP欺骗详解 地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议.主机发送信息时将包含目标IP地址的ARP ...

  8. HTTP协议的头信息详解

    HTTP协议的头信息详解 http://blog.csdn.net/guoguo1980/archive/2008/07/14/2649658.aspx HTTP协议的头信息详解 HTTP(Hyper ...

  9. [转]HTTP协议之状态码详解

    HTTP协议之状态码详解 HTTP状态码,我都是现查现用. 我以前记得几个常用的状态码,比如200,302,304,404, 503. 一般来说我也只需要了解这些常用的状态码就可以了.  如果是做AJ ...

最新文章

  1. unit2--unit4单元文档
  2. 计算机应用技术多久退休,Windows 7正式退休 这些解决办法你必须了解
  3. 创造包容的环境和上升空间
  4. Python基础---容器集合Set
  5. java中FutureTask的使用
  6. shell变量里的字符替换
  7. OpenShift 4 - DevSecOps Workshop (13) - 将镜像推送到Quay,并进行漏洞扫描
  8. CVPR2022车道线检测Efficient Lane Detection via Curve Modeling
  9. 记一些印象深刻的 Bug
  10. 常用js或jq效果汇总
  11. linux运行jar包依赖,linux怎么打jar包
  12. 高等代数——大学高等代数课程创新教材(丘维声)——1.2笔记+习题
  13. 手机端html怎么复制到剪贴板,移动端和pc端的复制到剪贴板功能
  14. 移动互联网时代的创业机会
  15. java中怎么改变白天模式,android 白天黑夜模式切换例子源码
  16. python分割文本_切分文本Python
  17. IOS设备恢复模式和DFU模式 区别、进入方法
  18. 【ZZULIOJ】1055: 兔子繁殖问题
  19. 出入库管理系统php,php销售供应链管理系统
  20. web安全之--UrlRewrite

热门文章

  1. 鸿蒙2000plus,天玑2000plus处理器相当于骁龙的多少
  2. android开发界面转换,Android开发Activity界面切换添加动画特效的方法
  3. attempting to bokeyaunrun eclipse useing the jre instead of jdk,to run eclipse using
  4. iOS小技能:合并mp3格式的文件
  5. XiaomiRouter自学之路(13-U-boot支持web更新firmware功能)
  6. 根据NSDate得到农历的年份(包括生肖) 、月、日。
  7. 树莓派hc sr501 c语言,树莓派人体红外感应模块HC-SR501安装配置
  8. vue——ViewModel 简易原理
  9. 查看服务器ip修改记录,如果查看服务器ip地址和修改ip
  10. 安卓前端车牌识别技术