Linux编程基础 7.3:套接字本地通信

1 socket本地通信

socket原本是为网络通讯设计的,但后来在socket框架的基础上发展出了一种IPC(进程通信)机制,即UNIX Domain Socket,专门用来实现使用socket实现的本地进程通信。
本地通信的流程与使用的接口与基于TCP协议的网络通信模型相同,其大致流程如下:

  • (1)调用socket()函数通信双方进程创建各自的socket文件;
  • (2)定义并初始化服务器端进程的地址,并使用bind()函数将其与服务器端进程绑定;
  • (3)调用listen()函数监听客户端进程请求;
  • (4)客户端调用connect()函数,根据已明确的客户端进程地址,向服务器发送请求;
  • (5)服务器端调用accept()函数,处理客户端进程的请求,若客户端与服务器端进程成功建立连接,则双方进程可开始通信;
  • (6)通信双方以数据流的形式通过已创建的连接互相发送和接收数据,进行通信;
  • (7)待通信结束后,通信双方各自调用close()函数关闭连接。

与socket网络通信不同的是,在本地通信中用到的套接字的结构体类型为socket sockaddr_un。

2 本地通信案例

【案例1】使用socket实现本地进程间通信。

dmclient.c
#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 */
//创建客户端进程,成功返回0,出错返回小于0的errno
int cliConn(const char *paraName){int tempFd, tempLen, tempErr, tempRetVal;struct sockaddr_un tempSockUn;//创建本地套接字domainif ((tempFd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){return(-1);}//of if//使用自定义地址填充socket地址结构体memset(&tempSockUn, 0, sizeof(tempSockUn));tempSockUn.sun_family = AF_UNIX;sprintf(tempSockUn.sun_path, "%s%05d", CLI_PATH, getpid());tempLen = offsetof(struct sockaddr_un, sun_path) + strlen(tempSockUn.sun_path);unlink(tempSockUn.sun_path); //避免因文件已存在导致的bind()失败if (bind(tempFd, (struct sockaddr *)&tempSockUn, tempLen ) < 0) {tempRetVal = -2;goto errout;}//of if//使用服务器进程地址填充socket地址结构体memset(&tempSockUn, 0, sizeof(tempSockUn));tempSockUn.sun_family = AF_UNIX;strcpy(tempSockUn.sun_path, paraName);tempLen = offsetof(struct sockaddr_un, sun_path) + strlen(paraName);if (connect(tempFd, (struct sockaddr *)&tempSockUn, tempLen) < 0) {tempRetVal = -4;goto errout;}//of ifreturn(tempFd);
errout:tempErr = errno;close(tempFd);errno = tempErr;return(tempRetVal);
}//of cliConnint main(void) {int tempFd, tempDataLen;char tempBuf[1024];tempFd = cliConn("foo.socket");		//套接字文件为foo.socketif (tempFd < 0) {						//容错处理switch (tempFd) {case -4:perror("connect"); break;case -3:perror("listen"); break;case -2:perror("bind"); break;case -1:perror("socket"); break;}//of switchexit(-1);}//of ifwhile (fgets(tempBuf, sizeof(tempBuf), stdin) != NULL) {write(tempFd, tempBuf, strlen(tempBuf));tempDataLen = read(tempFd, tempBuf, sizeof(tempBuf));write(STDOUT_FILENO, tempBuf, tempDataLen);}//of whileclose(fd);return 0;
}//of maindmserver.c
#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
//创建服务器进程,成功返回0,出错返回小于0的errno
int servListen(const char *paraName) {int tempFd, tempLen, tempErr, tempRetVal;struct sockaddr_un tempSockUn;//创建本地domain套接字if ((tempFd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){return(-1);}//of if//删除套接字文件,避免因文件存在导致bind()绑定失败	unlink(paraName);//初始化套接字结构体地址memset(&tempSockUn, 0, sizeof(tempSockUn));tempSockUn.sun_family = AF_UNIX;strcpy(tempSockUn.sun_path, paraName);tempLen = offsetof(struct sockaddr_un, sun_path) + strlen(paraName);if (bind(tempFd, (struct sockaddr *)&tempSockUn, tempLen) < 0) {tempRetVal = -2;goto errout;}//of ifif (listen(tempFd, QLEN) < 0) { //告知内核这是一个服务器进程tempRetVal = -3;goto errout;}//of ifreturn(tempFd);
errout:tempErr = errno;close(tempFd);errno = tempErr;return(tempRetVal);
}//of servListenint servAccept(int paraListenfd, uid_t *paraUidPtr) {int tempCliFd, tempLen, tempErr, tempRetVal;time_t tempStaleTime;struct sockaddr_un tempSockUn;struct stat tempStatBuf;tempLen = sizeof(tempSockUn);if ((tempCliFd = accept(paraListenfd, (struct sockaddr *)&tempSockUn, &tempLen)) < 0){return(-1);}//of if//从调用地址获取客户端的uidtempLen -= offsetof(struct sockaddr_un, sun_path); //获取路径名长度tempSockUn.sun_path[tempLen] = 0; 	//为路径名字符串添加终止符if (stat(tempSockUn.sun_path, &tempStatBuf) < 0) {tempRetVal = -2;goto errout;}//of ifif (S_ISSOCK(tempStatBuf.st_mode) == 0) {tempRetVal = -3; 				//若返回值为-3,说明这不是一个socket文件goto errout;}//of ifif (paraUidPtr != NULL){*paraUidPtr = tempStatBuf.st_uid; 		//返回uid的调用者指针}//of if//到此成功获取路径名unlink(tempSockUn.sun_path);return(tempCliFd);
errout:tempErr = errno;close(tempCliFd);errno = tempErr;return(tempRetVal);
}//of servAcceptint main(void) {int tempListenFd, tempAcceptFd, tempDataLen, i;uid_t tempAcceptUid;char tempBuf[1024];tempListenFd = serv_listen("foo.socket");if (tempListenFd < 0) {switch (tempListenFd) {case -3:perror("listen"); break;case -2:perror("bind"); break;case -1:perror("socket"); break;}//of switchexit(-1);}//of iftempAcceptFd = serv_accept(tempListenFd, &tempAcceptUid);if (tempAcceptFd < 0) {switch (tempAcceptFd) {case -3:perror("not a socket"); break;case -2:perror("a bad filename"); break;case -1:perror("accept"); break;}//of switchexit(-1);}//of ifwhile (1) {r_again:tempDataLen = read(tempAcceptFd, tempBuf, 1024);if (tempDataLen == -1) {if (errno == EINTR){goto r_again;}//of if} else if (tempDataLen == 0) {printf("the other side has been closed.\n");break;}//of iffor (i = 0; i < n; i++){tempBuf[i] = toupper(tempBuf[i]);}//of for iwrite(tempAcceptFd, tempBuf, tempDataLen);}close(tempAcceptFd);close(tempListenFd);return 0;
}//of main

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

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

相关文章

乔布斯在斯坦福大学演讲稿英文_西方大文豪最爱的10个英文单词,写尽人世间细腻情感!...

从小浸染在汉语中的我们&#xff0c;常被汉字的意象美震撼到&#xff0c;一字就是一世界。汉字有种无与伦比的美丽&#xff0c;寥寥数字就能营造“只可意会不可言传”的意境&#xff0c;很多人感慨英文就是一串拉丁字母&#xff0c;无法传递细腻的情感。比如很多人说像「缘分」…

dorado 刷新_dorado7常用内容

tabControl").set("currentTab","tab2");// 通过tab的索引(index)属性切换view.get("#tabControl").set("currentIndex",1);//根据名字切换tabvar tab self.get("currentTab").get("name");if(tab!"ta…

web前端开发论文写作_外语论文文献引言格式—MLA Style

我们之前讨论了外语论文文献引用格式—APA Style和Chicago Style—芝加哥论文脚注引注格式&#xff0c;今天我们来介绍在Essay写作中如何使用APA格式引用文献。MLA格式是英文论文写作最常用的一种参考文献格式。很多留学小伙伴都觉得MLA引用格式很复杂&#xff0c;今天译然小编…

Linux编程基础--目录

本系列教程以《Linux编程基础》为基础&#xff0c;希望在大家的帮助下&#xff0c;逐步完善Linux下系统级程序设计。 1 初识Linux 1.1 课程简介及Linux介绍 2 Linux文件操作 2.1 文件I/O 2.2 文件操作 3 进程管理 3.1 进程控制 3.2 exec家族 3.3 进程同步 4 信号 4.1 系…

100999凑整到万位进一_四年级数学专项练习

填空题1、当除数是34时&#xff0c;试商时可以把除数看作( )&#xff0c;这样初商容易偏( )。2、()个26相加的和是468&#xff1b;()比12个15多20。3、34&#xff1d;21……&#xff0c;余数最大是()&#xff0c;这时被除数是()。4、在括号里填上合适的数。480秒()分540厘米()分…

cosx等价无穷小_第一章 函数与极限 第七节 无穷小的比较

我的公众号“每日晴天”&#xff0c;可关注领取我的笔记pdf版哦~------------------------------------------------------------------------------本文主要首先把书上的定义和知识点总结起来&#xff0c;方便复习要点背诵&#xff0c;同时在最后分割线之后补充自己当时在学习…

Linux编程基础 8.1:多进程并发服务器

多进程并发服务器 多线程并发服务器 I/O多路转接服务器 epoll的工作模式 1 多进程并发服务器 在多进程并发服务器中&#xff0c;若有用户请求到达&#xff0c;服务器将会调用fork()函数&#xff0c;创建一个子进程&#xff0c;之后父进程将继续调用accept()&#xff0c;而子进…

pmbok第七版_PMBOK第七版要来了!都有哪些变化?你准备好了么?

PMBOK第7版#PMP##职场##项目管理##战略##价值#2020年1月15日PMBOK 第7版的征求意见稿发布&#xff0c;并于2020年1月14日结束意见征集&#xff0c;预计于今年第四季度发布。基于我的项目组合管理(PfMP)&#xff0c;项目集管理(PgMP),项目管理(PMP)的培训和研究经验&#xff0c;…

Linux编程基础 8.2:多线程并发服务器

2 多线程并发服务器 每个进程可打开的文件描述符数量有限&#xff0c;且进程占用资源较多&#xff0c;系统中进程的数量又受到内存大小的限制&#xff0c;为保证服务器效率&#xff0c;降低服务器消耗&#xff0c;可利用多线程机制搭建并发服务器。 【案例2】搭建多线程并发服…

简述python的特性_Python的特性概要

1、和C比较&#xff0c;Python是解释型的语言&#xff0c; 2、a>字节码特性 b>动态语义&#xff0c;即在赋值时才确定数据类型 c>缩进&#xff0c;点击tap键缩进四个空格&#xff0c;使用编译器是记得查看&#xff01;3、注意 写Python的时候首先要记得定义编码格式&a…

android netty导入_Android Netty框架的使用

public abstract class BaseClientMgr extends Subject implementsIClientConnect {protected boolean isRunning; //当前是否正在连接protected boolean isSending; //是否正在发送 线程是否被占用private int mPort; //连接服务器的端口号private int mCommunication; //通讯…

python自动化办公实例展示_python自动化办公?学这些就够用了

知乎上有人提问&#xff1a;用python进行办公自动化都需要学习什么知识呢&#xff1f;这可能是很多非IT职场人士面临的困惑&#xff0c;想把python用到工作中&#xff0c;却不知如何下手&#xff1f; python在自动化办公领域越来越受欢迎&#xff0c;批量处理简直是加班族的福音…

Linux编程基础 8.3:I/O多路转接服务器

1 简介 为进一步提升服务器效率&#xff0c;人们提出了一种被称为I/O多路转接的模型。其中“多路”指代连接到服务器的多个客户端程序&#xff0c;而“转接”则是指在服务器主线与各分支之间设置一个“岗位”&#xff0c;由该岗位实现监控多路连接中数据状态的功能&#xff0c…

handler原子锁_多线程编程之原子锁

在《多线程编程之数据访问互斥》一文中简单介绍了原子锁&#xff0c;这里再详细说一下原子锁的概念和用途。(1)简单数据操作如果在一个多线程环境下对某个变量进行简单数学运算或者逻辑运算&#xff0c;那么就应该使用原子锁操作。因为&#xff0c;使用临界区、互斥量等线程互斥…

python统计中文字符的个数_python统计中文字符数量的两种方法

方法一&#xff1a; def str_count(str): 找出字符串中的中英文、空格、数字、标点符号个数 count_en count_dg count_sp count_zh count_pu 0 for s in str: # 英文 if s in string.ascii_letters: count_en 1 # 数字 elif s.isdigit(): count_dg 1 # 空格 elif s.issp…

测井储层参数预测+人工智能方法

1 问题描述 测井储层参数预测 地层泥质含量&#xff1b;地层孔隙度&#xff08;POR&#xff09;&#xff1b;含水饱和度&#xff08;SW&#xff09;&#xff1b;渗透率&#xff08;PERM&#xff09;。 输入&#xff1a;声波时差&#xff08;AC&#xff09;、补偿中子&#x…

php spry文本域_Spry框架及验证构件

图9-71Spry框架原理虽然这些文件存放在服务器上&#xff0c;但实际上是被加载到浏览器中运行的。框架的用户将所有需要的文件链接到HTML文档中&#xff0c;以使用不同的组件&#xff0c;来获得更丰富的用户体验。Spry框架是和设计人员紧密相关的&#xff0c;因此框架中的每个元…

网络系统安全课程--目录

本系列教程以《网络与系统安全》为基础&#xff0c;希望在大家的帮助下&#xff0c;逐步完善网络与系统安全研究生课程。 1 经典攻击分析 1.1 中间人攻击 1.2 源替换攻击 1.3 消息重放攻击 1.4 平行会话攻击 1.5 反射攻击 1.6 交错攻击 1.7 类型缺陷攻击 1.8 身份标识省略导致…

windows 安装openssh服务端_Git神器| SourceTree安装使用教程

SourceTree 是 Windows 和Mac OS X 下免费的Git客户端管理工具。支持创建、克隆、提交、push、pull 和合并等操作。一、sourcetree的安装1. 下载sourcetree下载链接&#xff1a;Sourcetree | Free Git GUI for Mac and Windows2. 安装sourcetree点击安装&#xff0c;第一个创建…

c语言小学生四则运算出题_软件工程第一次作业,小学生四则运算的出题程序...

一、背景阿超有个儿子上小学二年级&#xff0c;老师每天让家长给孩子出30道加减法题&#xff0c;虽然不多&#xff0c;但是每天都做也算是个负担&#xff0c;阿超作为一个老牌程序员当然想用计算机来解决这个小问题&#xff0c;目前对于这个问题对于任何语言都不是问题&#xf…