本地进程间通信

进程间通信-Socket

Socket是一种接口技术,可以让不同的进程进行通信,有两种方式:既可以同一计算机上的,也可以是不同计算机上的进程。

同一计算机上socket通信:

注意:底层需要借助socket文件,进行同一台计算机下不同进程之间的通信

int socket(int domain, int type, int protocol);
功能:创建socket对象
domain:
    AF_UNIX,AF_LOCAL 选择使用socket文件进行通信
type:
	SOCK_STREAM    数据流
    SOCK_DGRAM		数据报
protocol:
        特殊协议,一般写0即可
返回值:socket对象的描述符,错误返回负值        
        
准备通信地址:
struct sockaddr_un
{
    int sun_family;		//与domain一致即可
    char sun_path[108];		/* 地址名 */
};

绑定socket对象和通信地址:会自动创建socket文件
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);    
功能:绑定通信地址和socket
sockfd:socket对象的描述符
addr:
    实际传递的是sockaddr_un或sockaddr_in,但是要统一转换成sockaddr
addrlrn:地址结构体的字节数,用于区别sockaddr_un,sockaddr_in。
返回值:成功返回0,失败返回-1

    
使用于SOCK_DGRAM报文的通信函数
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
功能:发送数据
sockfd:socket对象描述符
buf:要发送的数据首地址
len:要发送数据的字节数 
flags:是否阻塞,写0即可
dest_addr:通信目标的地址
addrlen:地址结构体的字节数
返回值:成功发送的字节数,
    -1 出现错误
    0  通信关闭


ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
功能:接收数据
sockfd:socket对象描述符
buf:缓冲区首地址
len:缓冲区大小
flags:是否阻塞,写0即可
src_addr:用于存储发送者的地址
addrlen:既是输入,也是输出,
    1、告诉系统src_addr的字节数
    2、系统反馈实际到的发送者的地址字节数
返回值:成功接收到的字节数
    -1 出现错误
    0  通信关闭

本地进程间通信

进程A

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>


int main(int argc,const char* argv[])
{
	// 创建socket对象
	int sock = socket(AF_UNIX,SOCK_DGRAM,0); //UNIX本地使用 DGRAM报文通信
	if(0 > sock)
	{
		perror("socket");
		return -1;
	}

	// 准备通信地址
	struct sockaddr_un addr = {};  // sockaddr_un 本地连接时的数据结构
	addr.sun_family = AF_UNIX;
	sprintf(addr.sun_path,"local_socketA");
	socklen_t addrlen = sizeof(addr);

	// 绑定socket对象与地址,创建一个用于接收数据的socket文件
	if(bind(sock,(struct sockaddr*)&addr,addrlen))
	{
		perror("bind");
		return -1;
	}

	char buf[4096] = {};
	for(;;)
	{
		// 存储发送的地址
		struct sockaddr_un src_addr = {};
		// 接收数据和数据来源
		int ret = recvfrom(sock,buf,sizeof(buf),0,(struct sockaddr*)&src_addr,&addrlen);
		
		printf("recv:%s len:%d\n",buf,ret);
		if(ret <= 0 || 0 == strcmp(buf,"quit"))
		{
			printf("通信结束!\n");
			break;
		}

		printf(">>>");
		gets(buf);
		
		// 返回数据
		ret = sendto(sock,buf,strlen(buf)+1,0,(struct sockaddr*)&src_addr,addrlen);
		
		printf("send len:%d\n",ret);
		if(ret <= 0 || 0 == strcmp(buf,"quit"))
		{
			printf("通信结束!\n");
			break;
		}
	}

	// 关闭socket对象
	close(sock);
	// 删除socket文件
	remove(addr.sun_path);
}

进程B

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>


int main(int argc,const char* argv[])
{
	// 创建socket对象
	int sock = socket(AF_UNIX,SOCK_DGRAM,0);
	if(0 > sock)
	{
		perror("socket");
		return -1;
	}

	// 准备自己通信地址
	struct sockaddr_un addr = {} , dest_addr = {};
	addr.sun_family = AF_UNIX;
	sprintf(addr.sun_path,"local_socketB");
	socklen_t addrlen = sizeof(addr);

	// 绑定socket对象与地址,创建一个用于接收数据的socket文件
	if(bind(sock,(struct sockaddr*)&addr,addrlen))
	{
		perror("bind");
		return -1;
	}
	
	// 目标的地址
	dest_addr.sun_family = AF_UNIX;
	sprintf(dest_addr.sun_path,"local_socketA");


	for(;;)
	{
		char buf[4096] = {};
		printf(">>>");
		gets(buf);		//数据写入
		int ret = sendto(sock,buf,strlen(buf)+1,0,(struct sockaddr*)&dest_addr,addrlen);
		printf("send len:%d\n",ret);
		if(ret <= 0 || 0 == strcmp(buf,"quit"))
		{
			printf("通信结束!\n");
			break;
		}
		
		ret = recvfrom(sock,buf,sizeof(buf),0,(struct sockaddr*)&dest_addr,&addrlen);
		printf("recv:%s len:%d\n",buf,ret);		//程序B检测输出字符
		if(ret <= 0 || 0 == strcmp(buf,"quit"))
		{
			printf("通信结束!\n");
			break;
		}	
	}

	close(sock);
	remove(addr.sun_path);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值