UNIX域套接字(UDS) 原理及比较(linux域套接字)
yuyutoo 2025-03-24 01:15 5 浏览 0 评论
什么是UDS
Unix domain socket 又叫 IPC(inter-process communication 进程间通信) socket,用于实现同一主机上的进程间通信。socket 原本是为网络通讯设计的,但后来在 socket 的框架上发展出一种 IPC 机制,就是 UNIX domain socket。虽然网络 socket 也可用于同一台主机的进程间通讯(通过 loopback 地址 127.0.0.1),但是 UNIX domain socket 用于 IPC 更有效率:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。这是因为,IPC 机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。
UNIX domain socket 是全双工的,API 接口语义丰富,相比其它 IPC 机制有明显的优越性,目前已成为使用最广泛的 IPC 机制,比如 X Window 服务器和 GUI 程序之间就是通过 UNIX domain socket 通讯的。
IP socket
IP socket要利用主机的传输层(tcp),可以用于同一台主机上不同进程间的通信,也可以用于网络上不同主机间的通信。
Unix domain socket vs IP socket
先来看一个使用案例,配置php-fpm与Nginx交互的socket:
fastcgi_pass 127.0.0.1:9000 fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock
这个案例中,运行在同一台机器上的php和Nginx需要通信,有2种实现方式:第一种是ip socket,通过本机回环地址127.0.0.1加端口实现;第二种是通过unix domain socket实现。哪一种效率更高呢?
基于localhost的ip socket需要实现跨网络主机通讯的全部环节,包括建立socket连接,ACk开销,tcp流控,封装/解封,路由。在这个过程中还会有2个context switch,因为使用网络层传输数据需要调用system call,而调用system call会产生中断,导致context switch的;另外一个进程接受到来自网络层的连接请求,也会产生系统中断,导致context switch。以上过程导致2个context switch的开销,外加其它各种开销(overhead)。
unix域的数据报服务是否可靠
man unix 手册即可看到,unix domain socket 的数据报既不会丢失也不会乱序 (据我所知,在Linux下的确是这样)。不过最新版本的内核,仍然又提供了一个保证次序的类型 “ kernel 2.6.4 SOCK_SEQPACKET ”。
STREAM 和 DGRAM 的主要区别
既然数据报不丢失也可靠,那不是和 STREAM 很类似么?我理解也确实是这样,而且我觉得 DGRAM 相对还要好一些,因为发送的数据可以带边界。二者另外的区别在于收发时的数据量不一样,基于 STREAM 的套接字,send 可以传入超过 SO_SNDBUF 长的数据,recv 时同 TCP 类似会存在数据粘连。
采用阻塞方式使用API,在unix domain socket 下调用 sendto 时,如果缓冲队列已满,会阻塞。而UDP因为不是可靠的,无法感知对端的情况,即使对端没有及时收取数据,基本上sendto都能立即返回成功(如果发端疯狂sendto就另当别论,因为过快地调用sendto在慢速网络的环境下,可能撑爆套接字的缓冲区,导致sendto阻塞)。
SO_SNDBUF 和 SO_REVBUF
对于 unix domain socket,设置 SO_SNDBUF 会影响 sendto 最大的报文长度,但是任何针对 SO_RCVBUF 的设置都是无效的 。实际上 unix domain socket 的数据报还是得将数据放入内核所申请的内存块里面,再由另一个进程通过 recvfrom 从内核读取,因此具体可以发送的数据报长度受限于内核的 slab 策略 。在 linux 平台下,早先版本(如 2.6.2)可发送最大数据报长度约为 128 k ,新版本的内核支持更大的长度。
使用 DGRAM 时,缓冲队列的长度
有几个因素会影响缓冲队列的长度,一个是上面提到的 slab 策略,另一个则是系统的内核参数
/proc/sys/net/unix/max_dgram_qlen。缓冲队列长度是这二者共同决定的。
如 max_dgram_qlen 默认为 10,在数据报较小时(如1k),先挂起接收数据的进程后,仍可以 sendto 10 次并顺利返回;
但是如果数据报较大(如120k)时,就要看 slab “size-131072” 的 limit 了。
使用 unix domain socket 进行进程间通信 vs 其他方式
· 需要先确定操作系统类型,以及其所对应的最大 DGRAM 长度,如果有需要传送超过该长度的数据报,建议拆分成几个发送,接收后组装即可(不会乱序,个人觉得这样做比用 STREAM 再切包方便得多)
· 同管道相比,unix 域的数据报不但可以维持数据的边界,还不会碰到在写入管道时的原子性问题。
· 同共享内存相比,不能独立于进程缓存大量数据,但是却避免了同步互斥的考量。
· 同普通 socket 相比,开销相对较小(不用计算报头),DGRAM 的报文长度可以大于 64k,不过不能像普通 socket 那样将进程切换到不同机器 。
UNIX域套接字使用文件系统作为地址名称空间。这意味着您可以使用UNIX文件权限来控制通信访问和他们在一起。即则可以限制其他进程可以连接到守护进程——可能一个用户可以,但是web服务器不能,或者类似的情况。有了IP套接字,连接守护进程的能力就暴露出来了目前的系统,所以可能需要采取额外的步骤安全。另一方面,网络透明。与UNIX域套接字,实际上可以检索进程的凭据创建了远程套接字,并将其用于访问控制,这在多用户系统上非常方便。-本地主机上的IP套接字基本上是在回环网络IP。故意“没有特殊知识”的事实是连接到相同的系统,所以不做任何努力来绕过基于性能原因的常规IP堆栈机制。例如,TCP上的传输总是涉及两个上下文切换远程插座,因为你必须通过netisr切换发生在通过合成的包的“环回”之后环回接口。同样地,你会得到所有的ack开销,TCP流量控制,封装/封装等路由执行,以决定包是否发送到本地主机。大的发送必须被分解成mtu大小的数据报还增加了大型写操作的开销。它实际上是TCP,它只是去一个环回接口,通过一个特殊的地址,或发现请求的地址在本地提供,而不是通过以太网提供(等)。- UNIX域套接字有明确的知识,他们正在执行同样的系统。它们避免了额外的上下文切换和发送线程将直接写入流或数据进入接收套接字缓冲区。没有计算校验和,没有插入标头,不执行路由,等等,因为它们有访问远程socket缓冲区,也可以直接提供在填写时反馈给发件人,或者更重要的是,清空,而不是增加显式的开销确认和窗口更改。一个功能UNIX域套接字不提供TCP提供的是带外数据。在实践,这是一个几乎无人关注的问题。一般来说,在TCP上实现的理由是它给你位置独立性和即时可移植性——您可以移动客户机或者这个守护进程,更新一个地址,它就会“正常工作”。套接字层提供了通信服务的合理抽象,所以编写一个连接/绑定的应用程序并不难部分了解TCP和UNIX域套接字,其余的只是使用它给出的套接字。所以如果你想在局部寻找性能,我认为UNIX域套接字可能最能满足您的需要。许多人因为性能通常不那么重要,所以无论如何都要编码到TCP吗网络可移植性的好处是巨大的。现在,UNIX域套接字代码被一个子系统锁覆盖;我有一个版本使用了更细粒度的锁定,但是还没有评估这些更改对性能的影响。你跑进来了在一个有四个处理器的SMP环境中,这些变化是可能的可能会对性能产生积极的影响,所以如果您喜欢这些补丁。现在他们在我的时间表上开始测试,但不是在包含在FreeBSD 5.4中的路径。更大的主要好处粒度应该是如果您有许多对线程/进程使用UNIX域套接字在处理器之间进行通信在UNIX域套接字子系统锁上存在大量争用。补丁不会增加正常的发送/接收操作的成本,但是在listen/accept/connect/bind路径中添加额外的互斥操作。
API操作
函数介绍
开始创建socket
int socket(int domain, int type, int protocol)
domain(域) : AF_UNIX
type : SOCK_STREAM/ SOCK_DGRAM :
protocol : 0
SOCK_STREAM(流) : 提供有序,可靠的双向连接字节流。 可以支持带外数据传输机制,
无论多大的数据都不会截断
SOCK_DGRAM(数据报):支持数据报(固定最大长度的无连接,不可靠的消息),数据报超过最大长度,会被截断.
获取到socket文件描述符之后,还要将其绑定一个文件上
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockfd : 传入sock的文件描述符
addr : 用sockaddr_un表示
addrlen : 结构体长度
struct sockaddr_un { sa_family_t sun_family; /* AF_UNIX */ char sun_path[UNIX_PATH_MAX]; /* pathname */ };
监听客户端的连接
int listen(int sockfd, int backlog);
sockfd : 文件描述符
backlog : 连接队列的长度
接受客户端的连接
int accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len);
UDS不存在客户端地址的问题,因此这里的addr和addrlen参数可以设置为NULL
相关推荐
- ETCD 故障恢复(etc常见故障)
-
概述Kubernetes集群外部ETCD节点故障,导致kube-apiserver无法启动。...
- 在Ubuntu 16.04 LTS服务器上安装FreeRADIUS和Daloradius的方法
-
FreeRADIUS为AAARadiusLinux下开源解决方案,DaloRadius为图形化web管理工具。...
- 如何排查服务器被黑客入侵的迹象(黑客 抓取服务器数据)
-
---排查服务器是否被黑客入侵需要系统性地检查多个关键点,以下是一份详细的排查指南,包含具体命令、工具和应对策略:---###**一、快速初步检查**####1.**检查异常登录记录**...
- 使用 Fail Ban 日志分析 SSH 攻击行为
-
通过分析`fail2ban`日志可以识别和应对SSH暴力破解等攻击行为。以下是详细的操作流程和关键分析方法:---###**一、Fail2ban日志位置**Fail2ban的日志路径因系统配置...
- 《5 个实用技巧,提升你的服务器安全性,避免被黑客盯上!》
-
服务器的安全性至关重要,特别是在如今网络攻击频繁的情况下。如果你的服务器存在漏洞,黑客可能会利用这些漏洞进行攻击,甚至窃取数据。今天我们就来聊聊5个实用技巧,帮助你提升服务器的安全性,让你的系统更...
- 聊聊Spring AI Alibaba的YuQueDocumentReader
-
序本文主要研究一下SpringAIAlibaba的YuQueDocumentReaderYuQueDocumentReader...
- Mac Docker环境,利用Canal实现MySQL同步ES
-
Canal的使用使用docker环境安装mysql、canal、elasticsearch,基于binlog利用canal实现mysql的数据同步到elasticsearch中,并在springboo...
- RustDesk:开源远程控制工具的技术架构与全场景部署实战
-
一、开源远程控制领域的革新者1.1行业痛点与解决方案...
- 长安汽车一代CS75Plus2020款安装高德地图7.5
-
不用破解原车机,一代CS75Plus2020款,安装车机版高德地图7.5,有红绿灯读秒!废话不多讲,安装步骤如下:一、在拨号状态输入:在电话拨号界面,输入:*#518200#*(进入安卓设置界面,...
- Zookeeper使用详解之常见操作篇(zookeeper ui)
-
一、Zookeeper的数据结构对于ZooKeeper而言,其存储结构类似于文件系统,也是一个树形目录服务,并通过Key-Value键值对的形式进行数据存储。其中,Key由斜线间隔的路径元素构成。对...
- zk源码—4.会话的实现原理一(会话层的基本功能是什么)
-
大纲1.创建会话...
- Zookeeper 可观测性最佳实践(zookeeper能够确保)
-
Zookeeper介绍ZooKeeper是一个开源的分布式协调服务,用于管理和协调分布式系统中的节点。它提供了一种高效、可靠的方式来解决分布式系统中的常见问题,如数据同步、配置管理、命名服务和集群...
- 服务器密码错误被锁定怎么解决(服务器密码错几次锁)
-
#服务器密码错误被锁定解决方案当服务器因多次密码错误导致账户被锁定时,可以按照以下步骤进行排查和解决:##一、确认锁定状态###1.检查账户锁定状态(Linux)```bash#查看账户锁定...
- zk基础—4.zk实现分布式功能(分布式zk的使用)
-
大纲1.zk实现数据发布订阅...
- 《死神魂魄觉醒》卡死问题终极解决方案:从原理到实战的深度解析
-
在《死神魂魄觉醒》的斩魄刀交锋中,游戏卡死犹如突现的虚圈屏障,阻断玩家与尸魂界的连接。本文将从技术架构、解决方案、预防策略三个维度,深度剖析卡死问题的成因与应对之策,助力玩家突破次元壁障,畅享灵魂共鸣...
你 发表评论:
欢迎- 一周热门
-
-
前端面试:iframe 的优缺点? iframe有那些缺点
-
带斜线的表头制作好了,如何填充内容?这几种方法你更喜欢哪个?
-
漫学笔记之PHP.ini常用的配置信息
-
推荐7个模板代码和其他游戏源码下载的网址
-
其实模版网站在开发工作中很重要,推荐几个参考站给大家
-
[干货] JAVA - JVM - 2 内存两分 [干货]+java+-+jvm+-+2+内存两分吗
-
正在学习使用python搭建自动化测试框架?这个系统包你可能会用到
-
织梦(Dedecms)建站教程 织梦建站详细步骤
-
【开源分享】2024PHP在线客服系统源码(搭建教程+终身使用)
-
2024PHP在线客服系统源码+完全开源 带详细搭建教程
-
- 最近发表
-
- ETCD 故障恢复(etc常见故障)
- 在Ubuntu 16.04 LTS服务器上安装FreeRADIUS和Daloradius的方法
- 如何排查服务器被黑客入侵的迹象(黑客 抓取服务器数据)
- 使用 Fail Ban 日志分析 SSH 攻击行为
- 《5 个实用技巧,提升你的服务器安全性,避免被黑客盯上!》
- 聊聊Spring AI Alibaba的YuQueDocumentReader
- Mac Docker环境,利用Canal实现MySQL同步ES
- RustDesk:开源远程控制工具的技术架构与全场景部署实战
- 长安汽车一代CS75Plus2020款安装高德地图7.5
- Zookeeper使用详解之常见操作篇(zookeeper ui)
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)