C语言两种方法实现进程间 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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值