UNIX域套接字编程和socketpair 函数
一、UNIX Domain Socket IPC
socket
API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain
Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain
Socket用于IPC更有效率:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。UNIX域套接字与TCP套接字相比较,在同一台主机的传输速度前者是后者的两倍。这是因为,IPC机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。UNIX
Domain Socket也提供面向流和面向数据包两种API接口,类似于TCP和UDP,但是面向消息的UNIX Domain
Socket也是可靠的,消息既不会丢失也不会顺序错乱。
使用UNIX Domain
Socket的过程和网络socket十分相似,也要先调用socket()创建一个socket文件描述符,address
family指定为AF_UNIX,type可以选择SOCK_DGRAM或SOCK_STREAM,protocol参数仍然指定为0即可。
UNIX Domain Socket与网络socket编程最明显的不同在于地址格式不同,用结构体sockaddr_un表示,网络编程的socket地址是IP地址加端口号,而UNIX Domain Socket的地址是一个socket类型的文件在文件系统中的路径,这个socket文件由bind()调用创建,如果调用bind()时该文件已存在,则bind()错误返回。
#define UNIX_PATH_MAX 108
struct sockaddr_un {
sa_family_t
sun_family; /* AF_UNIX */
char sun_path[UNIX_PATH_MAX]; /* pathname */
};
二、回射/客户服务器程序
通信的流程跟前面说过的tcp/udp 是类似的,下面直接来看程序:
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
/*************************************************************************
> File Name: echoser_tcp.c > Author: Simba > Mail: dameng34@163.com > Created Time: Sun 03 Mar 2013 06:13:55 PM CST ************************************************************************/ #include<stdio.h> #define ERR_EXIT(m) \ void echo_ser(int conn) memset(recvbuf, 0, sizeof(recvbuf)); ERR_EXIT("read error"); else if (n == 0) fputs(recvbuf, stdout); close(conn); /* unix domain socket与TCP套接字相比较,在同一台主机的传输速度前者是后者的两倍。*/ unlink("/tmp/test socket"); //地址复用 if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) if (listen(listenfd, SOMAXCONN) < 0) int conn; while (1) conn = accept(listenfd, NULL, NULL); if (conn == EINTR) pid = fork(); close(conn); return 0; |
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
/*************************************************************************
> File Name: echocli_tcp.c > Author: Simba > Mail: dameng34@163.com > Created Time: Sun 03 Mar 2013 06:13:55 PM CST ************************************************************************/ #include<stdio.h> #include<stdio.h> #define ERR_EXIT(m) \ void echo_cli(int conn) write(conn, sendbuf, strlen(sendbuf)); close(conn); int main(void) struct sockaddr_un servaddr; if (connect(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) echo_cli(sock); return 0; |
server 使用fork 的形式来接受多个连接,server调用bind 会创建一个文件,如下所示:
simba@ubuntu:~/Documents/code/linux_programming/UNP/socket$ ls -l /tmp/test\ socket
srwxrwxr-x 1 simba simba 0 Jun 12 15:27 /tmp/test socket
即文件类型为s,表示SOCKET文件,与FIFO(命名管道)文件,类型为p,类似,都表示内核的一条通道,读写文件实际是在读写内核通道。程序中调用unlink(解除硬链接) 是为了在开始执行程序时删除以前创建的文件,以便在重启服务器时不会提示address in use。其他方面与以前说过的回射客户服务器程序没多大区别,不再赘述。
三、UNIX域套接字编程注意点
1、bind成功将会创建一个文件,权限为0777 & ~umask
2、sun_path最好用一个绝对路径
3、UNIX域协议支持流式套接口与报式套接口
4、UNIX域流式套接字connect发现监听队列满时,会立刻返回一个ECONNREFUSED,这和TCP不同,如果监听队列满,会忽略到来的SYN,这导致对方重传SYN。
四、socketpair 函数
功能:创建一个全双工的流管道
原型 int socketpair(int domain, int type, int protocol, int sv[2]);
参数
domain: 协议家族
type: 套接字类型
protocol: 协议类型
sv: 返回套接字对
返回值:成功返回0;失败返回-1
实际上socketpair 函数跟pipe 函数是类似的,也只能在同个主机上具有亲缘关系的进程间通信,但pipe 创建的匿名管道是半双工的,而socketpair 可以认为是创建一个全双工的管道。
可以使用socketpair 创建返回的套接字对进行父子进程通信:
|
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
/*************************************************************************
> File Name: echoser.c > Author: Simba > Mail: dameng34@163.com > Created Time: Fri 01 Mar 2013 06:15:27 PM CST ************************************************************************/ #include<stdio.h> #define ERR_EXIT(m) \ int main(void) if (socketpair(PF_UNIX, SOCK_STREAM, 0, sockfds) < 0) pid_t pid; if (pid > 0) ++val; } else if (pid == 0) int val; read(sockfds[1], &val, sizeof(val)); return 0; |
输出如下:
simba@ubuntu:~/Documents/code/linux_programming/UNP/socket$ ./socketpair
sending data: 1
recv data : 2
sending data: 3
recv data : 4
sending data: 5
recv data : 6
sending data: 7
recv data : 8
sending data: 9
recv data : 10
sending data: 11
recv data : 12
sending data: 13
recv data : 14
sending data: 15
recv data : 16
...................................
即父进程持有sockfds[0] 套接字进行读写,而子进程持有sockfds[1] 套接字进行读写。
参考:
《Linux C 编程一站式学习》
《TCP/IP详解 卷一》
《UNP》
UNIX域套接字编程和socketpair 函数的更多相关文章
- UNIX网络编程——UNIX域套接字编程和socketpair 函数
一.UNIX Domain Socket IPC socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket.虽然网络soc ...
- 通过UNIX域套接字传递描述符的应用
传送文件描述符是高并发网络服务编程的一种常见实现方式.Nebula 高性能通用网络框架即采用了UNIX域套接字传递文件描述符设计和实现.本文详细说明一下传送文件描述符的应用. 1. TCP服务器程 ...
- unix进程间通信方式(下)-unix域套接字(转)
在之前的博客中已经总结了其它7种进程间的通信方式.unix域套接字用于在同一台计算机上的进程间通信,虽然因特网域套接字可用于同一目的,但是unix域套接字的效率更高.unix域套接字并不进行协议处理, ...
- UNIX网络编程——通过UNIX域套接字传递描述符和 sendmsg/recvmsg 函数
在前面我们介绍了UNIX域套接字编程,更重要的一点是UNIX域套接字可以在同一台主机上各进程之间传递文件描述符. 下面先来看两个函数: #include <sys/types.h> #in ...
- 《网络编程》Unix 域套接字
概述 Unix 域套接字是一种client和server在单主机上的 IPC 方法.Unix 域套接字不运行协议处理,不须要加入或删除网络报头,无需验证和,不产生顺序号,无需发送确认报文,比因特网域套 ...
- 通过UNIX域套接字传递描述符和 sendmsg/recvmsg 函数
在前面我们介绍了UNIX域套接字编程,更重要的一点是UNIX域套接字可以在同一台主机上各进程之间传递文件描述符. 下面先来看两个函数: #include <sys/types.h> #i ...
- unix域套接字UDP网络编程
unix域套接字UDP网络编程,服务器如下面: #include <stdio.h> #include <stdlib.h> #include <string.h> ...
- 高级进程间通信之UNIX域套接字
UNIX域套接字用于在同一台机器上运行的进程之间的通信.虽然因特网域套接字可用于同一目的,但UNIX域套接字的效率更高.UNIX域套接字仅仅复制数据:它们并不执行协议处理,不需要添加或删除网络报头,无 ...
- UNIX域套接字(unix domain)
UNIX域套接字用于在同一台机器上运行的进程之间的通信. UNIX域套接字提供流和数据报两种接口. 说明:UNIX域套接字比因特网套接字效率更高.它仅赋值数据:不进行协议处理,如添加或删除网络报头.计 ...
随机推荐
- iOS开发-Interface Builder的前世今生
Interface Builder,是用于苹果公司Mac OS X操作系统的软件开发程序,Xcode套件的一部分,于1988年创立.它的创造者Jean-Marie Hullot自称是“一个热爱旅行.充 ...
- js常用的事件对象
事件源对象 event.srcElement.tagName event.srcElement.type 捕获释放 event.srcElement.setCapture(); event. ...
- html 空白汉字占位符
可以看作一个空白的汉字 == 普通的英文半角空格 == == == no-break space (普通的英文半角空格但不换行) == 中文全角空格 (一个中文宽度) == ...
- 顺序查找 && 折半查找
顺序查找 算法描述 顺序比较即可. 平均查找长度 (n+1)/2, 其中n为表长 ...
- DIRECT Project
http://www.healthit.gov/policy-researchers-implementers/direct-project Launched in March 2010 as a p ...
- 基于Java spring框架的微信企业号开发中关于js-sdk的配置
在调用js-sdk的第一步,我们需要引入js-sdk的js链接,然后执行wx.config,官方示例如下所示: wx.config({ debug: true, // 开启调试模式,调用的所有api的 ...
- chrome的护眼插件
- 体绘制(Volume Rendering)概述之3:光线投射算法(Ray Casting)原理和注意要点(强烈推荐呀,讲的很好)
转自:http://blog.csdn.net/liu_lin_xm/article/details/4850609 摘抄“GPU Programming And Cg Language Primer ...
- idea丢失svn解决办法
今天打开Idea,习惯用ctrl+t来更新svn,杯具出现了,快捷键失效了,我觉得可能是其他的什么软件占用了这个快捷键,于是把qq,微信,rtx,各种软件都关掉,发现还是不好使,于是重启了一下,发现还 ...
- iOS单元測试:Specta + Expecta + OCMock + OHHTTPStubs + KIF
框架选择 參考这篇选型文章,http://zixun.github.io/blog/2015/04/11/iosdan-yuan-ce-shi-xi-lie-dan-yuan-ce-shi-kuang ...