网站开发公司商业计划书国家备案网查询系统
news/
2025/10/6 11:07:22/
文章来源:
网站开发公司商业计划书,国家备案网查询系统,wordpress建站百科,辽宁建设厅官网1 socket本地通信
socket原本是为网络通讯设计的#xff0c;但后来在socket框架的基础上发展出了一种IPC#xff08;进程通信#xff09;机制#xff0c;即UNIX Domain Socket#xff0c;专门用来实现使用socket实现的本地进程通信。 本地通信的流程与使用的接口与基于TC…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/929249.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!