UNIX域套接字(UDS) 原理及比较(linux域套接字)
yuyutoo 2025-03-24 01:15 8 浏览 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
相关推荐
- 《保卫萝卜2》安卓版大更新 壕礼助阵世界杯
-
《保卫萝卜2:极地冒险》本周不仅迎来了安卓版本的重大更新,同时将于7月4日本周五,带来“保卫萝卜2”安卓版本世界杯主题活动的火热开启,游戏更新与活动两不误。一定有玩家会问,激萌塔防到底进行了哪些更新?...
- 儿童手工折纸:胡萝卜,和孩子一起边玩边学carrot
-
1、准备两张正方形纸,一橙一绿,对折出折痕。2、橙色沿其中一条对角线如图折两三角形。3、把上面三角折平,如图。4、绿色纸折成三角形。5、再折成更小的三角形。6、再折三分之一如图。7、打开折纸,压平中间...
- 《饥荒》食物代码有哪些(饥荒最新版代码总汇食物篇)
-
饥荒游戏中,玩家们需要获取各种素材与食物,进行生存。玩家们在游戏中,进入游戏后按“~”键调出控制台使用代码,可以直接获得素材。比如胡萝卜的代码是carrot,玉米的代码是corn,南瓜的代码是pump...
- Skyscanner:帮你找到最便宜机票 订票不求人
-
你喜欢旅行吗?在合适的时间、合适的目的地,来一场说走就走的旅行?机票就是关键!Skyscanner这款免费的手机应用,在几秒钟内比较全球600多家航空公司的航班安排、价格和时刻表,帮你节省金钱和时间。...
- 小猪佩奇第二季50(小猪佩奇第二季英文版免费观看)
-
Sleepover过夜Itisnighttime.现在是晚上。...
- 我在民政局工作的那些事儿(二)(我在民政局上班)
-
时间到了1997年的秋天,经过一年多的学习和实践,我在处理结婚和离婚的事情更加的娴熟,也获得了领导的器重,所以我在处理平时的工作时也能得心应手。这一天我正在离婚处和同事闲聊,因为离婚处几天也遇不到人,...
- 夏天来了就你还没瘦?教你不节食13天瘦10斤的哥本哈根减肥法……
-
好看的人都关注江苏气象啦夏天很快就要来了你是否和苏苏一样身上的肉肉还没做好准备?真是一个悲伤的故事……下面这个哥本哈根减肥法苏苏的同事亲测有效不节食不运动不反弹大家快来一起试试看吧~DAY1...
- Pursuing global modernization for peaceful development, mutually beneficial cooperation, prosperity for all
-
AlocalworkeroperatesequipmentintheChina-EgyptTEDASuezEconomicandTradeCooperationZonei...
- Centuries-old tea road regains glory as Belt and Road cooperation deepens
-
FUZHOU/ST.PETERSBURG,Oct.2(Xinhua)--NestledinthepicturesqueWuyiMountainsinsoutheastChi...
- Ftrace function graph简介(flat function)
-
引言由于android开发的需要与systrace的普及,现在大家在进行性能与功耗分析时候,经常会用到systrace跟pefetto.而systrace就是基于内核的eventtracing来实...
- JAVA历史版本(java各版本)
-
JAVA发展1.1996年1月23日JDK1.0Java虚拟机SunClassicVM,Applet,AWT2.1997年2月19日JDK1.1JAR文件格式,JDBC,JavaBea...
- java 进化史1(java的进阶之路)
-
java从1996年1月第一个版本诞生,到2022年3月最新的java18,已经经历了27年,整整18个大的版本。很久之前有人就说java要被淘汰,但是java活到现在依然坚挺,不知道java还能活...
- 学习java第二天(java学完后能做什么)
-
#java知识#...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- 《保卫萝卜2》安卓版大更新 壕礼助阵世界杯
- 儿童手工折纸:胡萝卜,和孩子一起边玩边学carrot
- 《饥荒》食物代码有哪些(饥荒最新版代码总汇食物篇)
- Skyscanner:帮你找到最便宜机票 订票不求人
- 小猪佩奇第二季50(小猪佩奇第二季英文版免费观看)
- 我在民政局工作的那些事儿(二)(我在民政局上班)
- 夏天来了就你还没瘦?教你不节食13天瘦10斤的哥本哈根减肥法……
- Pursuing global modernization for peaceful development, mutually beneficial cooperation, prosperity for all
- Centuries-old tea road regains glory as Belt and Road cooperation deepens
- 15 THE NUTCRACKERS OF NUTCRACKER LODGE (CONTINUED)胡桃夹子小屋里的胡桃夹子(续篇)
- 标签列表
-
- 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)