百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

UNIX域套接字(UDS) 原理及比较(linux域套接字)

yuyutoo 2025-03-24 01:15 3 浏览 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

相关推荐

Mysql和Oracle实现序列自增(oracle创建序列的sql)

Mysql和Oracle实现序列自增/*ORACLE设置自增序列oracle本身不支持如mysql的AUTO_INCREMENT自增方式,我们可以用序列加触发器的形式实现,假如有一个表T_WORKM...

关于Oracle数据库12c 新特性总结(oracle数据库19c与12c)

概述今天主要简单介绍一下Oracle12c的一些新特性,仅供参考。参考:http://docs.oracle.com/database/121/NEWFT/chapter12102.htm#NEWFT...

MySQL CREATE TABLE 简单设计模板交流

推荐用MySQL8.0(2018/4/19发布,开发者说同比5.7快2倍)或同类型以上版本....

mysql学习9:创建数据库(mysql5.5创建数据库)

前言:我也是在学习过程中,不对的地方请谅解showdatabases;#查看数据库表createdatabasename...

MySQL面试题-CREATE TABLE AS 与CREATE TABLE LIKE的区别

执行"CREATETABLE新表ASSELECT*FROM原表;"后,新表与原表的字段一致,但主键、索引不会复制到新表,会把原表的表记录复制到新表。...

Nike Dunk High Volt 和 Bright Spruce 预计将于 12 月推出

在街上看到的PandaDunk的超载可能让一些球鞋迷们望而却步,但Dunk的浪潮仍然强劲,看不到尽头。我们看到的很多版本都是为女性和儿童制作的,这种新配色为后者引入了一种令人耳目一新的新选择,而...

美国多功能舰载雷达及美国海军舰载多功能雷达系统技术介绍

多功能雷达AN/SPY-1的特性和技术能力,该雷达已经在美国海军服役了30多年,其修改-AN/SPY-1A、AN/SPY-1B(V)、AN/SPY-1D、AN/SPY-1D(V),以及雷神...

汽车音响怎么玩,安装技术知识(汽车音响怎么玩,安装技术知识视频)

全面分析汽车音响使用或安装技术常识一:主机是大多数人最熟习的音响器材,有关主机的各种性能及规格,也是耳熟能详的事,以下是一些在使用或安装时,比较需要注意的事项:LOUDNESS:几年前的主机,此按...

【推荐】ProAc Response系列扬声器逐个看

有考牌(公认好声音)扬声器之称ProAcTablette小音箱,相信不少音响发烧友都曾经,或者现在依然持有,正当大家逐渐掌握Tablette的摆位设定与器材配搭之后,下一步就会考虑升级至表现更全...

#本站首晒# 漂洋过海来看你 — BLACK&DECKER 百得 BDH2000L无绳吸尘器 开箱

作者:初吻给了烟sco混迹张大妈时日不短了,手没少剁。家里有了汪星人,吸尘器使用频率相当高,偶尔零星打扫用卧式的实在麻烦(汪星人:你这分明是找借口,我掉毛是满屋子都有,铲屎君都是用卧式满屋子吸的,你...

专题|一个品牌一件产品(英国篇)之Quested(罗杰之声)

Quested(罗杰之声)代表产品:Q212FS品牌介绍Quested(罗杰之声)是录音监听领域的传奇品牌,由英国录音师RogerQuested于1985年创立。在成立Quested之前,Roger...

常用半导体中英对照表(建议收藏)(半导体英文术语)

作为一个源自国外的技术,半导体产业涉及许多英文术语。加之从业者很多都有海外经历或习惯于用英文表达相关技术和工艺节点,这就导致许多英文术语翻译成中文后,仍有不少人照应不上或不知如何翻译。为此,我们整理了...

Fyne Audio F502SP 2.5音路低音反射式落地音箱评测

FyneAudio的F500系列,有新成员了!不过,新成员不是新的款式,却是根据原有款式提出特别版。特别版产品在原有型号后标注了SP字样,意思是SpecialProduction。Fyne一共推出...

有哪些免费的内存数据库(In-Memory Database)

以下是一些常见的免费的内存数据库:1.Redis:Redis是一个开源的内存数据库,它支持多种数据结构,如字符串、哈希表、列表、集合和有序集合。Redis提供了快速的读写操作,并且支持持久化数据到磁...

RazorSQL Mac版(SQL数据库查询工具)

RazorSQLMac特别版是一款看似简单实则功能非常出色的SQL数据库查询、编辑、浏览和管理工具。RazorSQLformac特别版可以帮你管理多个数据库,支持主流的30多种数据库,包括Ca...

取消回复欢迎 发表评论: