科技 > 操作系统 > Unix

Andorid进程间通信之 UNIX SOCKET

163人参与 2024-08-06 Unix

1,什么是unix socket
unix socket,域套接字,unix socket可用于同一台设备进程间通信,它不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序列号应答等,只需要将数据从一个进程复制到另一个进程,有两种类型,字节流套接字和数据报套接字。类似于tcp和udp,但是面向消息的unix socket也是可靠的,消息既不会丢失也不会顺序错乱

2,unix socket工作流程图
在这里插入图片描述
3,unix socket的方法
使用unix socket一般需要包含两个头文件

#include <sys/types.h>          /* see notes */
#include <sys/socket.h>

这里主要说明unix socket相比于socket不同的两个方法(传入的参数有差异,方法名是一致的),其它的方法都和socket通讯的方法是一样的。

1,int socket(int domain, int type, int protocol)
该方法用于创建套接字,各参数的含义:

domain决定了socket的地址类型。对于af_unix/af_local,地址类型为

struct sockaddr_un {
     sa_family_t  sun_family;       /* af_unix 或 af_local */
     char         sun_path[108];    /* pathname */

socket执行成功的话,返回一个文件描述符,失败的话返回 -1

2,int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
该方法用于对地址进行绑定,各参数的含义如下:

bind执行成功返回0,失败返回 -1

4,unix socket进程间通讯实战
服务端:

#include <stdio.h>
#include <sys/types.h>			/* see notes */
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <unistd.h>
#define my_sock_path "/dev/server-socket"
#define listen_backlog 50

int main(){
	int result;
	int listenfd,connfd;
	struct sockaddr_un my_addr,peer_addr;
	socklen_t peer_addr_size;
	char buf[512];
	
	listenfd = socket(af_unix, sock_stream, 0);//1,创建套接字,注意传入的参数
	if(listenfd < 0){
		printf("socket error!\n");
		return -1;
	}

	memset(&my_addr, 0, sizeof(struct sockaddr_un));
	my_addr.sun_family = af_unix;
	strcpy(my_addr.sun_path, my_sock_path);
	socklen_t len = sizeof(my_addr.sun_family)+strlen(my_sock_path);
	unlink(my_sock_path);
	result = bind(listenfd,(struct sockaddr *)&my_addr,len);//2,绑定
	if(result < 0){
		printf("bind error!\n");
		return -1;
	}
	printf("bind sucess!\n");
	result = listen(listenfd, listen_backlog);//3,添加监听
	if(result<0){
		printf("listen error!\n");
		return -1;
	}
	printf("listen....!\n");
	while(1){
		peer_addr_size = sizeof(struct sockaddr_un);
        connfd = accept(listenfd, (struct sockaddr *) &peer_addr,&peer_addr_size);//,4,等待客户端连接,返回的是连接的客户端的文件描述符
		if(connfd < 0){
			printf("accept error!\n");
			continue;
		}
		while(1){
			memset(buf,0,sizeof(buf));
			int len = read(connfd,buf,sizeof(buf));//从客户端读取数据
			printf("server len:%d\n",len);
			if(len < 0){
				printf("read error!\n");
				break;
			}else if(len == 0){
				printf("eof!\n");
				break;
			}else{
				buf[len] = '\n';
				printf("server recive buf:%s\n",buf);
				if(strncmp(buf,"quit",4) == 0){
					break;
				}else{
					buf[0] = 'a';
					write(connfd,buf,len);//把数据写给客户端
				}
			}
		}
		close(connfd);
	}
	close(listenfd);
	return 0;
}

客户端:

#include <stdio.h>
#include <sys/types.h>			/* see notes */
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <unistd.h>


#define my_sock_path "/dev/server-socket"

int main(){
	int socket_fd,result;
	struct sockaddr_un my_addr;
	char buf[512]={0};
	
	socket_fd = socket(af_unix, sock_stream, 0);//1,创建socket

	if(socket_fd<0){
		printf("socket error!\n");
		return -1;
	}

	memset(&my_addr, 0, sizeof(struct sockaddr_un));
	my_addr.sun_family = af_unix;
	strncpy(my_addr.sun_path, my_sock_path,sizeof(my_addr.sun_path) - 1);
	result =  connect(socket_fd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr_un));//2,连接
	if(result<0){
		printf("connect error!\n");
		return -1;
	}

	printf("please input buf:\n");
	while(fgets(buf,sizeof(buf),stdin) != null){
		write(socket_fd,buf,sizeof(buf));
		int len = read(socket_fd,buf,sizeof(buf));
		printf("read len:%d!\n",len);
		if(len<=0){
			printf("read error!\n");
			break;
		}else{
			printf("client recive buf:%s\n",buf);
		}
		
		printf("please input buf:\n");
	}

	close(socket_fd);

	return 0;
}

运行结果:

please input buf:
hjd
server len:512
server recive buf:hjd

read len:512!
client recive buf:ajd

可以看到发送给服务端的buf,经过服务端的处理后(将首个字符变成a),返回给了客户端

(0)
打赏 微信扫一扫 微信扫一扫

您想发表意见!!点此发布评论

推荐阅读

银河麒麟V10+达梦数据库DM8环境,安装UnixODBC驱动

08-06

【gitlab】failed to receive response: dial unix /var/opt/gitlab/gitlab-rails/sockets/g

08-06

无法使用docker|ERROR: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker

08-06

板凳---------unix网络编程卷1:第二章传输层:TCP、UDP 和 SCTP

08-06

整理FreeBSD系统安装时关于硬盘参数提示的处理方法

09-08

Windows 安装 GCC

08-03

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论