Linux进程间通信:socket套接字

最近写代码需要进程间socket通信,于是上网查了一些资料,自己动手写代码实现了一下,最后发现其实 socket 进程通信与网络通信使用的是统一套接口,只是地址结构与某些参数不同。

第一种实现方案:使用 “127.0.0.1”

客户端程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <unistd.h>
 
//#define UNIX_DOMAIN "/tmp/UNIX.domain"
#define DATELEN 1024
 
int main(int argc, char *argv[])
{
	int GuiConnect_fd = -1;
	int iRet = -1;
	int iRecvLen = 0;
	int iSendLen = 0;
	char GuiSendBuf[DATELEN] = {0};
	char GuiRecvBuf[DATELEN] = {0};
 
	//static struct sockaddr_un ServAddr;
	struct sockaddr_in ServAddr;
 
	//creat unix socket
	//GuiConnect_fd = socket(PF_UNIX, SOCK_STREAM, 0);
	GuiConnect_fd = socket(AF_INET, SOCK_STREAM, 0);
	printf("== GuiConnect_fd = %d\n", GuiConnect_fd);
 
	if (GuiConnect_fd < 0)
	{
		perror("cannot create communication socket");
		return 1;
	}
 
	//ServAddr.sun_family = AF_UNIX;
	//strncpy(ServAddr.sun_path, UNIX_DOMAIN, sizeof(ServAddr.sun_path) - 1);
 
	memset(&ServAddr, 0, sizeof(ServAddr));
	ServAddr.sin_family = AF_INET;
	ServAddr.sin_port = htons(5050);
	ServAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
 
	//connect server
	iRet = connect(GuiConnect_fd, (struct sockaddr*)&ServAddr, sizeof(ServAddr));
	if(-1 == iRet)
	{
		perror("cannot connect to the server");
		close(GuiConnect_fd);
		return 1;
	}
 
	//receive and send message
	memset(GuiRecvBuf, 0, DATELEN);
	printf("GUI Receie Msg from TDC\n");
	//iRecvLen = read(GuiConnect_fd, GuiRecvBuf, sizeof(GuiRecvBuf));
	iRecvLen = recv(GuiConnect_fd, GuiRecvBuf, DATELEN, 0);
	printf("receive message from server (%d) :%s\n", iRecvLen, GuiRecvBuf);
	printf("GUI Send msg to TDC server:\n");
	memset(GuiSendBuf, 0, DATELEN);
	strcpy(GuiSendBuf, "receive message from GUI client\n");
	GuiSendBuf[strlen(GuiSendBuf)] = '\0';
	//iSendLen = write(GuiConnect_fd, GuiSendBuf, sizeof(GuiSendBuf));
	iSendLen = send(GuiConnect_fd, GuiSendBuf, strlen(GuiSendBuf), 0);
	printf("wrint Date Len to server (%d) : %s\n", iSendLen, GuiSendBuf);
 
	close(GuiConnect_fd);
 
	return 0;
}
服务端程序
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <unistd.h>
 
//#define UNIX_DOMAIN "/tmp/UNIX.domain"
#define MAXClIENT 10
#define DATELEN 1024 //TDC 和 GUI 进程间通信数据长度
 
int main(int argc, char *argv[])
{
	int iRet = -1;
	int iRecvLen = 0;
	int iCltAddrLen = 0;
	int TdcServer_fd = -1;
	int GuiClient_fd = -1;
	char TdcRecvBuf[DATELEN] = {0}; 
	char TdcSendBuf[DATELEN] = {0}; 
	//struct sockaddr_un CltAddr;
	//struct sockaddr_un SrvAddr;
	struct sockaddr_in CltAddr;
	struct sockaddr_in SrvAddr;
 
	//unlink(UNIX_DOMAIN); //保证没有已经存在的文件
 
	//creat server socket 
	//TdcServer_fd = socket(PF_UNIX, SOCK_STREAM, 0);
	TdcServer_fd = socket(AF_INET, SOCK_STREAM, 0);
	printf(" === TdcServer_fd = %d\n", TdcServer_fd);
	if (TdcServer_fd < 0)
	{
		perror("TDC cannot create communication socket");
		return 1;
	}  
 
	//set server addr_param
	//SrvAddr.sun_family = AF_UNIX;//IPV4
	//strncpy(SrvAddr.sun_path, UNIX_DOMAIN, sizeof(SrvAddr.sun_path) - 1);
	memset(&SrvAddr,0,sizeof(SrvAddr));
	SrvAddr.sin_family = AF_INET;
	SrvAddr.sin_port = htons(5050);  //这里输入服务器端口号
	SrvAddr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY表示本机IP
 
	//bind sockfd & addr
	iRet = bind(TdcServer_fd, (struct sockaddr*)&SrvAddr, sizeof(SrvAddr));
	if (-1 == iRet)
	{
		perror("cannot bind server socket");
		close(TdcServer_fd);
		// unlink(UNIX_DOMAIN);
		return 1;
	}
 
	//listen sockfd 
	iRet = listen(TdcServer_fd, MAXClIENT);
	if (-1 == iRet)
	{
		perror("cannot listen the client connect request");
		close(TdcServer_fd);
		// unlink(UNIX_DOMAIN);
		return 1;
	}
 
	//have connect request use accept
	iCltAddrLen = sizeof(CltAddr);
 
	while(1)
	{
		GuiClient_fd = accept(TdcServer_fd, (struct sockaddr*)&CltAddr, &iCltAddrLen);
		printf("============== GuiClient_fd = %d\n", GuiClient_fd);
		if(GuiClient_fd < 0)
		{
			perror("cannot accept client connect request");
			close(TdcServer_fd);
			// unlink(UNIX_DOMAIN);
			return 1;
		}
 
		//read and printf sent client info
		memset(TdcSendBuf, 0, DATELEN);
		strcpy(TdcSendBuf, "you have connected to TDC succeed, NOW Receive msg from server\n");
		//write(GuiClient_fd, TdcSendBuf, sizeof(TdcSendBuf));
		printf("== GuiClient_fd = %d\n", GuiClient_fd);
		send(GuiClient_fd, TdcSendBuf, strlen(TdcSendBuf), 0);
		memset(TdcRecvBuf, 0, DATELEN);
		//sleep(5);
		//iRecvLen = read(GuiClient_fd, TdcRecvBuf, sizeof(TdcRecvBuf));
		printf("receiveing .....\n");
 
		while (1)
		{
			iRecvLen = recv(GuiClient_fd, TdcRecvBuf, DATELEN, 0);
			printf("Message from client (%d)) :%s/n", iRecvLen, TdcRecvBuf);
		}
	}
 
	close(GuiClient_fd);
	close(TdcServer_fd);
	//unlink(UNIX_DOMAIN);
 
	return 0;
}

第二种方法实现:使用unix域本地socket (个人简单理解为本地读写文件)

客户端程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <unistd.h>
 
#define UNIX_DOMAIN "/tmp/UNIX.domain"
#define DATELEN 1024
 
int main(int argc, char *argv[])
{
	int GuiConnect_fd = -1;
	int iRet = -1;
	int iRecvLen = 0;
	int iSendLen = 0;
	char GuiSendBuf[DATELEN] = {0};
	char GuiRecvBuf[DATELEN] = {0};
 
	static struct sockaddr_un ServAddr;
	//struct sockaddr_in ServAddr;
 
	//creat unix socket
	GuiConnect_fd = socket(PF_UNIX, SOCK_STREAM, 0);
	//GuiConnect_fd = socket(AF_INET, SOCK_STREAM, 0);
	printf("== GuiConnect_fd = %d\n", GuiConnect_fd);
 
	if (GuiConnect_fd < 0)
	{
		perror("cannot create communication socket");
		return 1;
	}
 
	ServAddr.sun_family = AF_UNIX;
	strncpy(ServAddr.sun_path, UNIX_DOMAIN, sizeof(ServAddr.sun_path) - 1);
 
	//memset(&ServAddr, 0, sizeof(ServAddr));
	//ServAddr.sin_family = AF_INET;
	//ServAddr.sin_port = htons(5050);
	//ServAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
 
	//connect server
	iRet = connect(GuiConnect_fd, (struct sockaddr*)&ServAddr, sizeof(ServAddr));
	if(-1 == iRet)
	{
		perror("cannot connect to the server");
		close(GuiConnect_fd);
		return 1;
	}
 
	//receive and send message
	memset(GuiRecvBuf, 0, DATELEN);
	printf("GUI Receie Msg from TDC\n");
	//iRecvLen = read(GuiConnect_fd, GuiRecvBuf, sizeof(GuiRecvBuf));
	iRecvLen = recv(GuiConnect_fd, GuiRecvBuf, DATELEN, 0);
	printf("receive message from server (%d) :%s\n", iRecvLen, GuiRecvBuf);
	printf("GUI Send msg to TDC server:\n");
	memset(GuiSendBuf, 0, DATELEN);
	strcpy(GuiSendBuf, "receive message from GUI client\n");
	GuiSendBuf[strlen(GuiSendBuf)] = '\0';
	//iSendLen = write(GuiConnect_fd, GuiSendBuf, sizeof(GuiSendBuf));
	iSendLen = send(GuiConnect_fd, GuiSendBuf, strlen(GuiSendBuf), 0);
	printf("wrint Date Len to server (%d) : %s\n", iSendLen, GuiSendBuf);
 
	close(GuiConnect_fd);
 
	return 0;
}
服务端程序
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <unistd.h>
 
#define UNIX_DOMAIN "/tmp/UNIX.domain"
#define MAXClIENT 10
#define DATELEN 1024 //TDC 和 GUI 进程间通信数据长度
 
int main(int argc, char *argv[])
{
	int iRet = -1;
	int iRecvLen = 0;
	int iCltAddrLen = 0;
	int TdcServer_fd = -1;
	int GuiClient_fd = -1;
	char TdcRecvBuf[DATELEN] = {0}; 
	char TdcSendBuf[DATELEN] = {0}; 
	struct sockaddr_un CltAddr;
	struct sockaddr_un SrvAddr;
	//struct sockaddr_in CltAddr;
	//struct sockaddr_in SrvAddr;
 
	unlink(UNIX_DOMAIN); //保证没有已经存在的文件
 
	//creat server socket 
	TdcServer_fd = socket(PF_UNIX, SOCK_STREAM, 0);
	//TdcServer_fd = socket(AF_INET, SOCK_STREAM, 0);
	printf(" === TdcServer_fd = %d\n", TdcServer_fd);
	if (TdcServer_fd < 0)
	{
		perror("TDC cannot create communication socket");
		return 1;
	}  
 
	//set server addr_param
	SrvAddr.sun_family = AF_UNIX;//IPV4
	strncpy(SrvAddr.sun_path, UNIX_DOMAIN, sizeof(SrvAddr.sun_path) - 1);
	//memset(&SrvAddr,0,sizeof(SrvAddr));
	//SrvAddr.sin_family = AF_INET;
	//SrvAddr.sin_port = htons(5050);  //这里输入服务器端口号
	//SrvAddr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY表示本机IP
 
	//bind sockfd & addr
	iRet = bind(TdcServer_fd, (struct sockaddr*)&SrvAddr, sizeof(SrvAddr));
	if (-1 == iRet)
	{
		perror("cannot bind server socket");
		close(TdcServer_fd);
		unlink(UNIX_DOMAIN);
		return 1;
	}
 
	//listen sockfd 
	iRet = listen(TdcServer_fd, MAXClIENT);
	if (-1 == iRet)
	{
		perror("cannot listen the client connect request");
		close(TdcServer_fd);
		unlink(UNIX_DOMAIN);
		return 1;
	}
 
	//have connect request use accept
	iCltAddrLen = sizeof(CltAddr);
 
	while(1)
	{
		GuiClient_fd = accept(TdcServer_fd, (struct sockaddr*)&CltAddr, &iCltAddrLen);
		printf("============== GuiClient_fd = %d\n", GuiClient_fd);
		if(GuiClient_fd < 0)
		{
			perror("cannot accept client connect request");
			close(TdcServer_fd);
			unlink(UNIX_DOMAIN);
			return 1;
		}
 
		//read and printf sent client info
		memset(TdcSendBuf, 0, DATELEN);
		strcpy(TdcSendBuf, "you have connected to TDC succeed, NOW Receive msg from server\n");
		//write(GuiClient_fd, TdcSendBuf, sizeof(TdcSendBuf));
		printf("== GuiClient_fd = %d\n", GuiClient_fd);
		send(GuiClient_fd, TdcSendBuf, strlen(TdcSendBuf), 0);
		memset(TdcRecvBuf, 0, DATELEN);
		//iRecvLen = read(GuiClient_fd, TdcRecvBuf, sizeof(TdcRecvBuf));
		printf("receiveing .....\n");
 
		//while (1)
		{
			iRecvLen = recv(GuiClient_fd, TdcRecvBuf, DATELEN, 0);
			printf("Message from client (%d)) :%s/n", iRecvLen, TdcRecvBuf);
		}
	}
 
	close(GuiClient_fd);
	close(TdcServer_fd);
	unlink(UNIX_DOMAIN);
 
	return 0;
}


版权声明:本文为CSDN博主「三角函数sin」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sin0803/article/details/34875809

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值