网络协议之: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/
最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!
欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!
网络协议之:socket协议详解之Unix domain Socket的更多相关文章
- socket技术详解(看清socket编程)
socket编程是网络常用的编程,我们通过在网络中创建socket关键字来实现网络间的通信,通过收集大量的资料,通过这一章节,充分的了解socket编程,文章用引用了大量大神的分析,加上自己的理解,做 ...
- Unix domain socket
转载:http://www.cnblogs.com/chekliang/p/3222950.html socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是 ...
- linux一切皆文件之Unix domain socket描述符(二)
一.知识准备 1.在linux中,一切皆为文件,所有不同种类的类型都被抽象成文件(比如:块设备,socket套接字,pipe队列) 2.操作这些不同的类型就像操作文件一样,比如增删改查等 3.主要用于 ...
- HTTP协议 (六) 状态码详解
HTTP协议 (六) 状态码详解 HTTP状态码,我都是现查现用. 我以前记得几个常用的状态码,比如200,302,304,404, 503. 一般来说我也只需要了解这些常用的状态码就可以了. 如果 ...
- 第8章 应用协议 图解TCP/IP 详解
第8章 应用协议 图解TCP/IP 详解 8.1 应用层协议概要 应用层协议的定义 TCP和IP等下层协议是不依赖上层应用类型.实用性非常广的协议.而应用协议则是为了实现某种应用而设计和创造的协议. ...
- TCP协议粘包问题详解
TCP协议粘包问题详解 前言 在本章节中,我们将探讨TCP协议基于流式传输的最大一个问题,即粘包问题.本章主要介绍TCP粘包的原理与其三种解决粘包的方案.并且还会介绍为什么UDP协议不会产生粘包. 基 ...
- SSL协议之数据加密过程详解
前言 总括: 原文博客地址:SSL协议之数据加密过程详解 知乎专栏&&简书专题:前端进击者(知乎)&&前端进击者(简书) 博主博客地址:Damonare的个人博客 生活 ...
- Socket 死连接详解
Socket 死连接详解 当使用 Socket 进行通信时,由于各种不同的因素,都有可能导致死连接停留在服务器端,假如服务端需要处理的连接较多,就有可能造成服务器资源严重浪费,对此,本文将阐述其原理以 ...
- [转]网络性能评估工具Iperf详解(可测丢包率)
原文链接:安全运维之:网络性能评估工具Iperf详解:http://os.51cto.com/art/201410/454889.htm 参考博文:http://linoxide.com/monito ...
随机推荐
- 理解并手写 apply() 函数
apply()函数,在功能上类似于call(),只是传递参数的格式有所不同. dog.eat.call(cat, '鱼', '肉'); dog.eat.apply(cat, ['鱼', '肉']); ...
- LGP3346题解
广义 SAM 比较简单的题/fad 题意:树上所有路径一共能够组成多少个本质不同子串? 并且数据保证最多只有20个叶子节点. 我们先来考虑一下一种特殊情况: 对于路径 \([u,v]\),\(u\) ...
- Numpy库基础___四
Numpy数据存取 •数据的csv文件的存取 只能有效存取和读取一维和二维数据 a = np.arange(100).reshape(5,20) #用delimiter分割,默认为空格 np.save ...
- 使用虚拟机在CentOS上安装部署数据库使用
镜像下载.域名解析.时间同步请点击 阿里云开源镜像站 本节描述使用数据库的基本操作.通过此节您可以完成创建数据库.创建表及向表中插入数据和查询表中数据等操作. 2.1 前提条件 ●openGauss正 ...
- 如果一个service服务出现异常,无响应,如何定位,定位过程
假设一个service服务出现异常,要如何定位
- fastcgi未授权访问及任意命令执行
1. 漏洞原理 服务端使用fastcgi协议并对外网开放9000端口,攻击者可以构造fastcgi协议包内容,实现未授权访问服务端.php文件以及执行任意命令. 2. 漏洞利用 第一步 搭建vulhu ...
- C++设计模式 - 访问器模式(Visitor)
行为变化模式 在组件的构建过程中,组件行为的变化经常导致组件本身剧烈的变化."行为变化" 模式将组件的行为和组件本身进行解耦,从而支持组件行为的变化,实现两者之间的松耦合. 典型模 ...
- 到底为什么不建议使用SELECT *?
"不要使用SELECT *"几乎已经成为了MySQL使用的一条金科玉律,就连<阿里Java开发手册>也明确表示不得使用*作为查询的字段列表,更是让这条规则拥有了权威的加 ...
- C++11移动语义之一(基本概念)
摘要 移动语义是C++11的新特性之一,利用移动语义可以实现对象的移动而非拷贝.在某些情况下,可以大幅度的提升性能.本文将介绍C++11移动语义中的一些基本概念. 表达式 表达式是由一个或者多个运算对 ...
- Hashmap如何同步?
当我们需要一个同步的HashMap时,有两种选择: ●使用Collections.synchronizedMap(..)来同步HashMap. ●使用ConcurrentHashMap的 这两个选项之 ...