Domain Socket本地进程间通信

socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机
制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过
loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC更有效率:不需要经过网络协
议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷
贝到另一个进程。这是因为,IPC机制本质上是可靠的通讯,而网络协议是为不可靠的通讯
设计的。UNIX Domain Socket也提供面向流和面向数据包两种API接口,类似于TCP和UDP,
但是面向消息的UNIX Domain Socket也是可靠的,消息既不会丢失也不会顺序错乱。
UNIX Domain Socket是全双工的,API接口语义丰富,相比其它IPC机制有明显的优越
性,目前已成为使用最广泛的IPC机制,比如X Window服务器和GUI程序之间就是通过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()错误返回。
以下程序将UNIX Domain socket绑定到一个地址。

 

size = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);
#define offsetof(TYPE, MEMBER) ((int)&((TYPE *)0)->MEMBER)

server

#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#define QLEN 10
/*
* Create a server endpoint of a connection.
* Returns fd if all OK, <0 on error.
*/
int serv_listen(const char *name)
{
int fd, len, err, rval;
struct sockaddr_un un;
/* create a UNIX domain stream socket */
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
return(-1);
unlink(name); /* in case it already exists 否则bind的时候会出错*/
/* fill in socket address structure */
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
strcpy(un.sun_path, name);
len = offsetof(struct sockaddr_un, sun_path) + strlen(name);
/* bind the name to the descriptor 会创建name*/
if (bind(fd, (struct sockaddr *)&un, len) < 0) {
rval = -2;
goto errout;
}
if (listen(fd, QLEN) < 0) { /* tell kernel we're a server */
rval = -3;
goto errout;
}
return(fd);
errout:
err = errno;
close(fd);
errno = err;
return(rval);
}
int serv_accept(int listenfd, uid_t *uidptr)
{
int clifd, len, err, rval;
time_t staletime;
struct sockaddr_un un;
struct stat statbuf;
len = sizeof(un);
if ((clifd = accept(listenfd, (struct sockaddr *)&un, &len)) < 0)
return(-1); /* often errno=EINTR, if signal caught */
/* obtain the client's uid from its calling address */
len -= offsetof(struct sockaddr_un, sun_path); /* len of pathname */
un.sun_path[len] = 0; /* null terminate */
if (stat(un.sun_path, &statbuf) < 0) {
rval = -2;
goto errout;
}
if (S_ISSOCK(statbuf.st_mode) == 0) {
rval = -3; /* not a socket */
goto errout;
}
if (uidptr != NULL)
*uidptr = statbuf.st_uid; /* return uid of caller */
unlink(un.sun_path); /* we're done with pathname now */
return(clifd);
errout:
err = errno;
close(clifd);
errno = err;
return(rval);
}
int main(void)
{
int lfd, cfd, n, i;
uid_t cuid;
char buf[1024];
lfd = serv_listen("foo.socket");
if (lfd < 0) {
switch (lfd) {
case -3:perror("listen"); break;
case -2:perror("bind"); break;
case -1:perror("socket"); break;
}
exit(-1);
}
cfd = serv_accept(lfd, &cuid);
if (cfd < 0) {
switch (cfd) {
case -3:perror("not a socket"); break;
case -2:perror("a bad filename"); break;
case -1:perror("accept"); break;
}
exit(-1);
}
while (1) {
r_again:
n = read(cfd, buf, 1024);
if (n == -1) {
if (errno == EINTR)
goto r_again;
}
else if (n == 0) {
printf("the other side has been closed.\n");
break;
}
for (i = 0; i < n; i++)
buf[i] = toupper(buf[i]);
write(cfd, buf, n);
}
close(cfd);
close(lfd);
return 0;
}

 

client

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#define CLI_PATH "/var/tmp/" /* +5 for pid = 14 chars */
/*
* Create a client endpoint and connect to a server.
* Returns fd if all OK, <0 on error.
*/
int cli_conn(const char *name)
{
int fd, len, err, rval;
struct sockaddr_un un;
/* create a UNIX domain stream socket */
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
return(-1);
/* fill socket address structure with our address */
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
sprintf(un.sun_path, "%s%05d", CLI_PATH, getpid());
len = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);
unlink(un.sun_path); /* in case it already exists */
if (bind(fd, (struct sockaddr *)&un, len) < 0) {
rval = -2;
goto errout;
}
/* fill socket address structure with server's address */
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
strcpy(un.sun_path, name);
len = offsetof(struct sockaddr_un, sun_path) + strlen(name);
if (connect(fd, (struct sockaddr *)&un, len) < 0) {
rval = -4;
goto errout;
}
return(fd);
errout:
err = errno;
close(fd);
errno = err;
return(rval);
}
int main(void)
{
int fd, n;
char buf[1024];
fd = cli_conn("foo.socket");
if (fd < 0) {
switch (fd) {
case -4:perror("connect"); break;
case -3:perror("listen"); break;
case -2:perror("bind"); break;
case -1:perror("socket"); break;
}
exit(-1);
}
while (fgets(buf, sizeof(buf), stdin) != NULL) {
write(fd, buf, strlen(buf));
n = read(fd, buf, sizeof(buf));
write(STDOUT_FILENO, buf, n);
}
close(fd);
return 0;
}

 

转载于:https://www.cnblogs.com/xiangtingshen/p/10923350.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/411313.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php判断中英文请求,并实现跳转

PHP代码: <? $lan substr(?$HTTP_ACCEPT_LANGUAGE,0,5); if ($lan "zh-cn") print("<meta http-equivrefresh content 0;URL gb/index.htm>"); else print("<meta http-equivrefresh content 0;URL eng/index.htm>"); ?…

curl 请求日志_HTTP入门(一):在Bash中curl查看请求与响应

HTTP入门(一)&#xff1a;在Bash中curl查看请求与响应本文简单总结HTTP的请求与响应。本文主要目的是对学习内容进行总结以及方便日后查阅。详细教程和原理可以参考HTTP文档(MDN)。本文版权归马涛涛所有。本文所引用的图片和文字版权归原作者所有&#xff0c;侵权删。如有错误请…

下载android版趣步最新版,趣步下载2021安卓最新版_手机app官方版免费安装下载_豌豆荚...

程序需要调用以下重要权限&#xff1a;请求安装文件包- 允许程序请求安装文件包获取额外的位置信息提供程序命令- 允许程序访问额外的定位提供者指令修改或删除您的SD卡中的内容- 允许程序写入外部存储,如SD卡上写文件读取手机状态和身份- 访问电话状态读取您的SD卡中的内容- 允…

[html] 使用button当按钮和使用div当按钮有什么区别?

[html] 使用button当按钮和使用div当按钮有什么区别&#xff1f; button具有默认样式 button在表单中具有默认的提交事件 button具有disabled属性可以禁用个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨…

js基础---js组成以及基本认知

为什么要学js&#xff1f; 因为js无所不能&#xff0c;早期js是用来进行表单校验的&#xff1b;后来js误入歧途&#xff0c;用于实现小广告&#xff1b;再后来&#xff0c;ajax让js火了起来&#xff0c;可以实现无刷新更新数据&#xff0c;例如百度地图 也可以实现炫酷的网页特…

Virtools脚本语言(VSL)教程 - 枚举

enum关键字指定了一个枚举类型。枚举类型是一种用户定义的类型&#xff0c;由一套叫做计数器(enumerator)的赋之以名称的常量组成。缺省情况下&#xff0c;第一个计数器有一个为0的值&#xff0c;每个后续的计数器都比前一个的值更大(除非你显示地为特定计数器指定一个值)。 定…

入门指南_激光切管快速入门指南

本文是有关管材和激光管切割的思考的快速入门指南。要求首先&#xff0c;需要确定对管材尺寸的要求。考虑以下问题&#xff1a;将要加工的管材最大和最小直径是多少&#xff1f;切割这些管材需要多大功率&#xff1f;它们是薄壁还是厚壁&#xff1f;原材料和成品零件的长度是多…

[html] 百度、淘宝、京东移动端首页秒开是如何做到的?

[html] 百度、淘宝、京东移动端首页秒开是如何做到的&#xff1f; 我猜是&#xff0c;服务端渲染&#xff0c; 解决首屏加载慢的方式&#xff0c;个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目…

android+button+不可点击置灰,android:tint 给imagebutton着色 按钮灰色

直接在xml进行颜色变化&#xff0c;使用三目运算符。比如要给Imagebutton&#xff0c;在某个条件时变成灰色&#xff0c;其他变成OK色&#xff0c;直接在XML就搞定了&#xff1a;android:id"id/connect_ok_btn"android:layout_width"44dp"android:layout_h…

页面调试

1.network all 所有请求 XHR ajax请求 WS websocket请求 转载于:https://www.cnblogs.com/gzl180110/p/10930802.html

六步使用ICallbackEventHandler实现无刷新回调

ICallbackEventHandler存在于System.Web.UI中&#xff0c;我们先做一个非常简单的例子来试用一下。 第一步&#xff0c;在VS2005中建立一个新的WEB窗件。 第二步&#xff0c;在ASPX中&#xff0c;放上一段HTML代码(如下)&#xff1a; 1<body>2<form id"form1&…

hexo 环境变量_小白使用 Github + Hexo 从 0 搭建一个博客

最近有几位同学在公众号后台留言问我的博客站是怎么建站的&#xff0c;思来想去&#xff0c;还是写一篇从 0 开始吧。前置准备我们先聊一下前置准备&#xff0c;可能很多同学一听说要自己搭一个博客系统&#xff0c;直接就望而却步。不得有台服务器么&#xff0c;不得搞个数据库…

[html] 说说js代码写到html里还是单独写到js文件里哪个好?为什么?

[html] 说说js代码写到html里还是单独写到js文件里哪个好&#xff1f;为什么&#xff1f; js和html还是分开比较好&#xff0c;一是各功能独立&#xff0c;界面比较干净&#xff0c;二是方便管理&#xff0c;关系清晰&#xff0c;三是方便引用&#xff0c;一些公共js独立导入可…

android service交互,Android Activity与Service的交互方式

参考: http://blog.csdn.net/gebitan505/article/details/18151203实现更新下载进度的功能1. 通过广播交互Server端将目前的下载进度&#xff0c;通过广播的方式发送出来&#xff0c;Client端注册此广播的监听器&#xff0c;当获取到该广播后&#xff0c;将广播中当前的下载进度…

[转帖]AjaxControlToolkit.TabContainer 自定义样式续

Tabs控件其实是一个容器控件TabContainer和面板控件TabPanel。TabContainer控件用于包含TabPanel。TabPanel控件用于显示。下面来看一个示例&#xff1a;1)在VS2005中新建一个ASP.NET AJAX-Enabled Web Project项目工程&#xff0c;命名为Tabs。2)在Default.aspx页面上添加一个…

NodeMailer

刚开始学习MEAN, 搞个插件发个邮件。 NodeMailer貌似出镜率很高&#xff0c;用用。 https://nodemailer.com/smtp/ 先申请了个个人的Outlook的邮箱&#xff0c;测试了一把&#xff0c;顺利通过。耶&#xff0c;好激动。 const nodeMailer require(nodemailer);let transporte…

[html] 写一个布局,它的宽度是不固定的100%,如果让它的宽度始终是高度的一半呢?

[html] 写一个布局&#xff0c;它的宽度是不固定的100%&#xff0c;如果让它的宽度始终是高度的一半呢&#xff1f; <div class"ratio" style"--ratio: 0.5;"></div>.ratio {background-color: salmon;position: relative; }.ratio::before {…

c++ using 前置声明_每日优鲜前置仓模式的配货优化方案案例介绍

大渔导读&#xff1a;2019 年零售业供应链最佳实践大奖——银奖 基于每日优鲜前置仓模式的配货优化方案案例&#xff1b;1. 背景介绍&#xff1a; 每日优鲜成立于 2014 年 11 月&#xff0c;是专注于优质生鲜的移动电商&#xff0c;已在北上广深等全国 10 个核心城市建立“城市…

lg gw880 qq2011 android beta4版,LG GW880评测:CMMB天线、细节设计

机身侧面的银色边框与黑色的正面形成了鲜明的对比。不同于大部分的手机&#xff0c;LG GW880把电源/锁机键放到了机身左侧&#xff0c;而且还多了一个返回键&#xff0c;所以机身侧面设置了比较多的按键&#xff0c;设计比较复杂。机身右侧是拍照键、音量键以及数据线接口&…

数据库的事务,隔离级别和3大范式

*数据库事务的想关操作 1.事务开始:开始是一个事物,作为回滚的标记 2,回滚 rollback :回滚到上一个事务开始的地方, 或者回滚到某个存档点,期间没被 commit ; 操作都会被撤回 3.提交commit ;将事务中所有操作提交到数据库中 4.存档点:设置存档点方便回滚 *开始事务 ........确认…