- 浏览: 141081 次
文章分类
最新评论
Unix 域协议并不是一个实际的协议族,而是在单个主机上执行客户/服务器通信的一种方法,所用的 API 就是在不同主机上执行客户/服务器通信所用的套接字 API,可视为进程间通信(IPC)方法之一(POSIX 也把 Unix 域协议称为“本地 IPC”)。
Unix 域提供了两类套接字:字节流套接字(类似 TCP)和数据报套接字(类似 UDP)。尽管也提供原始套接字,不过不曾见过使用。使用 Unix 域套接字有以下 3 个理由。
(1)Unix 域套接字往往比位于同一个主机的 TCP 套接字快一倍。X Window System 就发挥了这个优势。当一个 X11 客户启动并打开到 X11 服务器的连接时,该客户会检查 DISPLAY 环境变量的值,其中指定了服务器的主机名、窗口和屏幕。如果服务器与客户处于同一个主机,客户就打开一个到服务器的 Unix 域字节流连接,否则打开一个 TCP 连接。
(2)Unix 域套接字可用于同一个主机上的不同进程之间传递描述符。
(3)Unix 域套接字较新的实现把客户的凭证(用户 ID 和组 ID)提供给服务器,从而能够提供额外的安全检查措施。
Unix 域中用于标识客户和服务器的协议地址是普通文件系统中的路径名,不过这些路径名不是普通的 Unix 文件:除非把它们关联到 Unix 域套接字,否则无法读写这些文件。
Unix 域套接字地址结构如下。
其中要注意的是,存放在 sun_path 数组中的路径名必须以空字符结尾。此外,因历史原因,虽然这里使用 104 来指明了 sun_path 的大小,但 POSIX 规范并没有明确规定 sun_path 的长度,因此应用程序应该在运行时使用 sizeof 运算符来计算 sockaddr_un 结构的大小。实现提供的 SUN_LEN 宏以一个指向 sockaddr_un 结构的指针为参数,并返回该结构的长度,其中包括路径名中的非空字节数。未指定地址通过以空字符串作为路径名指示,即 sun_path[0] 值为 0 的地址结构,它等价于 IPv4 的 INADDR_ANY 常值以及 IPv6 的 IN6ADDR_ANY_INIT 常值。
下面这个示例创建一个 Unix 域套接字,往其上 bind 一个路径名,再调用 getsockname 输出这个绑定的路径名。
程序运行结果如下:
创建的 Unix 域套接字的文件类型显示为“s”(有些系统把 Unix 域套接字视为 FIFO,从而显示为 p)。
为了方便,Unix 域套接字提供了 socketpair 函数,它可以创建两个随后连接起来的套接字。
这里,family 参数必须为 AF_LOCAL,protocol 参数必须为 0。type 参数可以是 SOCK_STREAM,也可以是 SOCK_DGRAM。sockfds 数组里就是保存的新创建的两个套接字描述符。
这样创建的两个套接字不曾命名,也就是说其中没有设计隐式的 bind 调用。指定 type 参数为 SOCK_STREAM 得到的结果称为流管道,它与调用 pipe 创建的普通 Unix 管道类似,差别在于流管道是全双工的,即两个描述符都是既可读又可写的,而 POSIX 并不要求 pipe 返回两个全双工的描述符。
虽然 Unix 域套接字用的也是套接字 API 函数,不过其中也还是存在如下一些差异和限制。
(1)由 bind 创建的路径名默认访问权限应为 0777,并按照当前的 umask 值进行修正。
(2)与 Unix 域套接字关联的路径名应该是一个绝对路径名,因为使用相当路径的话,对它的解析依赖于调用者的当前工作目录。
(3)在 connect 调用中指定的路径名必须是一个当前已经绑定在某个打开的 Unix 域套接字上的路径名,而且它们的套接字类型(字节流或数据报)也必须一致(即 Unix 域字节流套接字不能连接到与 Unix 域数据报套接字关联的路径名,反之亦然)。
(4)调用 connect 连接一个 Unix 域套接字涉及的权限测试等同于调用 open 以只写方式访问相应的路径名。
(5)Unix 域字节流套接字类似于 TCP 套接字:它们都为进程提供一个无记录边界的字节流接口。
(6)如果对于某个 Unix 域字节流套接字的 connect 调用发现该监听套接字的队列已满,调用就立即返回一个 ECONNREFUSED 错误。这一点不同于 TCP:如果 TCP 监听套接字的队列已满,TCP 监听端就忽略新到达的 SYN,而 TCP 连接发起端将数次发送 SYN 进行重试。
(7)Unix 域数据报套接字类似于 UDP 套接字:它们都提供一个保留记录边界的不可靠的数据报服务。
(8)在一个未绑定的 Unix 域套接字上发送数据报不会自动给这个套接字捆绑一个路径名,这一点不同于 UDP 套接字:在一个未绑定的 UDP 套接字上发送 UDP 数据报导致给这个套接字捆绑一个临时端口。这意味着除非数据报发送端已经捆绑一个路径名到它的套接字,否则数据报接收端无法发回应答数据报。类似地,对于某个 Unix 域数据报套接字的 connect 调用不会给本套接字捆绑一个路径名,这一点不同于 TCP 和 UDP。
Unix 域提供了两类套接字:字节流套接字(类似 TCP)和数据报套接字(类似 UDP)。尽管也提供原始套接字,不过不曾见过使用。使用 Unix 域套接字有以下 3 个理由。
(1)Unix 域套接字往往比位于同一个主机的 TCP 套接字快一倍。X Window System 就发挥了这个优势。当一个 X11 客户启动并打开到 X11 服务器的连接时,该客户会检查 DISPLAY 环境变量的值,其中指定了服务器的主机名、窗口和屏幕。如果服务器与客户处于同一个主机,客户就打开一个到服务器的 Unix 域字节流连接,否则打开一个 TCP 连接。
(2)Unix 域套接字可用于同一个主机上的不同进程之间传递描述符。
(3)Unix 域套接字较新的实现把客户的凭证(用户 ID 和组 ID)提供给服务器,从而能够提供额外的安全检查措施。
Unix 域中用于标识客户和服务器的协议地址是普通文件系统中的路径名,不过这些路径名不是普通的 Unix 文件:除非把它们关联到 Unix 域套接字,否则无法读写这些文件。
Unix 域套接字地址结构如下。
#include <sys/un.h> struct sockaddr_un{ sa_family_t sun_family; // AF_LOCAL char sun_path[104]; // null-terminated pathname };
其中要注意的是,存放在 sun_path 数组中的路径名必须以空字符结尾。此外,因历史原因,虽然这里使用 104 来指明了 sun_path 的大小,但 POSIX 规范并没有明确规定 sun_path 的长度,因此应用程序应该在运行时使用 sizeof 运算符来计算 sockaddr_un 结构的大小。实现提供的 SUN_LEN 宏以一个指向 sockaddr_un 结构的指针为参数,并返回该结构的长度,其中包括路径名中的非空字节数。未指定地址通过以空字符串作为路径名指示,即 sun_path[0] 值为 0 的地址结构,它等价于 IPv4 的 INADDR_ANY 常值以及 IPv6 的 IN6ADDR_ANY_INIT 常值。
下面这个示例创建一个 Unix 域套接字,往其上 bind 一个路径名,再调用 getsockname 输出这个绑定的路径名。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <strings.h> #include <sys/un.h> #include <sys/socket.h> typedef struct sockaddr SA; int main(int argc, char **argv){ if(argc != 2){ printf("Usage: unixBind <pathname>\n"); exit(2); } unlink(argv[1]); // OK if this fails struct sockaddr_un addr1, addr2; bzero(&addr1, sizeof(addr1)); addr1.sun_family = AF_LOCAL; strncpy(addr1.sun_path, argv[1], sizeof(addr1.sun_path)-1); int sockfd = socket(AF_LOCAL, SOCK_STREAM, 0); bind(sockfd, (SA *)&addr1, SUN_LEN(&addr1)); socklen_t len = sizeof(addr2); getsockname(sockfd, (SA *)&addr2, &len); printf("bound name = %s, returned len = %d\n", addr2.sun_path, len); exit(0); }
程序运行结果如下:
$ umask 0022 $ ./unixBind /tmp/moose bound name = /tmp/moose, returned len = 13 $ $ ./unixBind /tmp/moose # 再运行一次 bound name = /tmp/moose, returned len = 13 $ $ ls -l /tmp/moose srwxr-xr-x. 1 lei root 0 3月 12 00:37 /tmp/moose $ $ ls -lF /tmp/moose srwxr-xr-x. 1 lei root 0 3月 12 00:37 /tmp/moose= $
创建的 Unix 域套接字的文件类型显示为“s”(有些系统把 Unix 域套接字视为 FIFO,从而显示为 p)。
为了方便,Unix 域套接字提供了 socketpair 函数,它可以创建两个随后连接起来的套接字。
#include <sys/socket.h> int socketpair(int family, int type, int protocol, int sockfds[2]); /* 返回值:若成功则为 0,否则为 -1 */
这里,family 参数必须为 AF_LOCAL,protocol 参数必须为 0。type 参数可以是 SOCK_STREAM,也可以是 SOCK_DGRAM。sockfds 数组里就是保存的新创建的两个套接字描述符。
这样创建的两个套接字不曾命名,也就是说其中没有设计隐式的 bind 调用。指定 type 参数为 SOCK_STREAM 得到的结果称为流管道,它与调用 pipe 创建的普通 Unix 管道类似,差别在于流管道是全双工的,即两个描述符都是既可读又可写的,而 POSIX 并不要求 pipe 返回两个全双工的描述符。
虽然 Unix 域套接字用的也是套接字 API 函数,不过其中也还是存在如下一些差异和限制。
(1)由 bind 创建的路径名默认访问权限应为 0777,并按照当前的 umask 值进行修正。
(2)与 Unix 域套接字关联的路径名应该是一个绝对路径名,因为使用相当路径的话,对它的解析依赖于调用者的当前工作目录。
(3)在 connect 调用中指定的路径名必须是一个当前已经绑定在某个打开的 Unix 域套接字上的路径名,而且它们的套接字类型(字节流或数据报)也必须一致(即 Unix 域字节流套接字不能连接到与 Unix 域数据报套接字关联的路径名,反之亦然)。
(4)调用 connect 连接一个 Unix 域套接字涉及的权限测试等同于调用 open 以只写方式访问相应的路径名。
(5)Unix 域字节流套接字类似于 TCP 套接字:它们都为进程提供一个无记录边界的字节流接口。
(6)如果对于某个 Unix 域字节流套接字的 connect 调用发现该监听套接字的队列已满,调用就立即返回一个 ECONNREFUSED 错误。这一点不同于 TCP:如果 TCP 监听套接字的队列已满,TCP 监听端就忽略新到达的 SYN,而 TCP 连接发起端将数次发送 SYN 进行重试。
(7)Unix 域数据报套接字类似于 UDP 套接字:它们都提供一个保留记录边界的不可靠的数据报服务。
(8)在一个未绑定的 Unix 域套接字上发送数据报不会自动给这个套接字捆绑一个路径名,这一点不同于 UDP 套接字:在一个未绑定的 UDP 套接字上发送 UDP 数据报导致给这个套接字捆绑一个临时端口。这意味着除非数据报发送端已经捆绑一个路径名到它的套接字,否则数据报接收端无法发回应答数据报。类似地,对于某个 Unix 域数据报套接字的 connect 调用不会给本套接字捆绑一个路径名,这一点不同于 TCP 和 UDP。
发表评论
-
Unix 域套接字与描述符的传递
2019-03-27 23:59 710在Unix 域套接字概述一节中介绍了什么是 U ... -
kqueue 接口
2019-03-06 00:47 691kqueue 接口是 ... -
辅助数据
2019-02-28 00:40 687辅助数据(a ... -
recv/send 和 recvmsg/sendmsg 函数
2019-01-22 00:40 1553recv 和 send ... -
inetd 守护进程介绍
2019-01-09 21:51 1052在 4.3 BSD 系统之前,很多网络服务都是 ... -
主机名与 IP 地址的转换(续)
2018-12-25 00:37 955在主机名与 IP 地址的转换一节中提到的 ge ... -
主机名与 IP 地址的转换
2018-11-14 00:20 2306在网络编程中,尽管大部分情况下操作的都是 IP ... -
SCTP 事件通知
2018-02-08 03:49 984SCTP 提供了多种可用的通知,用户可经由这些通知追踪 ... -
SCTP 套接字选项
2018-02-04 09:35 1691在获取和设置套接 ... -
SCTP 套接字编程基础函数
2018-02-04 10:08 1055SCTP 服务器可以使 ... -
SCTP 套接字编程基础概念
2018-01-18 00:10 561SCTP 套接字分为一到一套接字和一到多套接字。提供一 ... -
UDP套接字编程基础
2018-01-14 10:37 574下图显示了使用 UDP 套接字编写客户/服务器程序时的 ... -
通用套接字选项
2018-01-02 00:46 551在获取和设置套接 ... -
获取和设置套接字选项
2017-12-29 08:21 440下面几种方法可用 ... -
I/O 复用之 poll 函数
2017-12-27 00:20 423poll 函数提供的功能与 select 类似,不过在 ... -
I/O 复用之select 函数
2017-12-12 00:32 516select 函数允许进 ... -
Unix 5 种 IO 模型概述
2017-11-19 01:44 305Unix 下有 5 种可用 ... -
套接字创建、连接和关闭函数
2017-08-13 17:16 664下图是一对 TCP 客户与服务器进程之间发生的一些典型 ... -
字节转换和填充函数
2017-08-06 01:09 428网络编程中,为保证发送协议栈和接收协议栈就如 32 位 ... -
IPv4 和 IPv6 的套接字地址结构
2017-08-01 21:03 738大多数套接字函数 ...
相关推荐
在Java中,使用Unix域协议编程时,可以利用Socket和ServerSocket类的构造函数,通过传入特定的Unix路径名来创建Unix域套接字。例如,ServerSocket的bind方法可以绑定到一个Unix路径,而Socket的connect方法可以连接...
- `PRU_CONNECT`请求处理函数`unp_connect()`建立与其他Unix域套接字的连接。 17.11中提到的其他请求处理函数也执行类似的职责,如PRU_LISTEN、PRU_ACCEPT、PRU_SHUTDOWN等,它们是Unix域协议中实现通信的关键部分...
库辅助使用 Unix 域套接字在进程之间传递文件描述符克隆概述这个库为可以在 Unix 域套接字上完成的黑魔法提供了一个简单的接口,比如将文件描述符从一个进程传递到另一个进程。 它应该 100% 符合 Single Unix ...
10. **UNIX域套接字**:除了网络套接字,书里还介绍了在同一主机内进程间通信的UNIX域套接字,它提供了更高效、更安全的通信方式。 以上只是《UNIX网络编程卷1:套接字联网API(第3版)》部分内容的概述,实际上,...
UNIX域套接字允许在同一台机器上的进程之间直接交换数据,类似于网络套接字,但效率更高,因为它们不需要网络层的开销。根据数据类型,UNIX域套接字可以是流式(SOCK_STREAM,类似TCP)或数据报式(SOCK_DGRAM,类似...
8. **高级主题**:涵盖了UNIX域套接字(用于同一主机上的进程间通信)、高性能服务器设计、多线程编程、套接字套件的安全性(SSL/TLS)以及网络时间协议(NTP)等。 9. **实例代码**:书中包含了大量的示例代码,...
此外,第二卷还涵盖了高级网络编程的主题,如UNIX域套接字、网络多路复用(select、poll和epoll)、非阻塞I/O、异步I/O模型,以及信号处理。这些技术可以帮助开发者设计出更加高效、灵活的网络应用程序。 最后,书...
17.4.2 经由UNIX域套接字传送文件描述符 17.5 open服务器版本1 17.6 open服务器版本2 17.7 小结 习题 第18章 终端I/O 18.1 引言 18.2 综述 18.3 特殊输入字符 18.4 获得和设置终端属性...
473 17.3 UNIX域套接字 476 17.3.1 命名UNIX域套接字 477 17.3.2 唯一连接 478 17.4 传送文件描述符 482 17.4.1 经由基于STREAMS的管道传送文件描述符 484 17.4.2 经由UNIX域套接字传送文件描述符 486 ...
4. **Unix域套接字**:仅限于本地主机上的进程间通信,提供比网络套接字更高的效率。 #### 小结 《Unix网络编程卷2》深入分析了Unix系统中的进程间通信技术,涵盖了消息传递、共享内存、信号量以及套接字等多种IPC...
第十三章 UNIX域套接字和并发服务器的预创建技术 13.1 UNIX域套接字 13.1.1 UNIX域的地址结构 13.1.2 UNIX(套接字使用的示例 13.1.3 传递文件描述符 13.2 并发服务器的预创建技术 ...
17.4.2 经由UNIX域套接字传送文件描述符 486 17.5 open服务器版本1 493 17.6 open服务器版本2 498 17.7 小结 505 习题 505 第18章 终端I/O 507 18.1 引言 507 18.2 综述 507 18.3 特殊输入字符 512...
同时,书中还讲解了如何使用UNIX域套接字实现本地进程间的通信,以及如何处理网络错误和异常情况。 ### 5. 系统调用与库函数 UNIX系统提供了大量的系统调用,允许程序员直接与操作系统内核交互。书中详细列举并...
第1章绪论.1 1.1操作系统概述1 1.1.1建立操作系统的目标1 1.1.2操作系统是用户与计算机的接口1 1.1.3操作系统是资源管理器2 1.2UNIX系统的主要特性3 1.3UNIX系统的发展史4 1.4开源软件与UNIX的推广发展6 1.4.1开源...
概述docs 测试 包裹 Manhole是一种进程内服务,它将接受unix域套接字连接,并显示所有线程的堆栈跟踪和交互式提示。 它可以作为工作在任何时候都Python守护线程等待连接或一个信号处理器(停止你的应用程序,并等待...