UNIX域套接字

1、UNIX域套接字的定义

UNIX域套接字是进程间通信(IPC)的一种方式,不涉及网络协议栈,因此在同一台主机上的通信中,它比基于TCP/IP协议的网络套接字更快速、更高效。

2、UNIX域套接字的分类

  • 字节流套接字(SOCK_STREAM):提供面向连接的、可靠的数据传输服务。
  • 数据报套接字(SOCK_DGRAM):提供无连接的数据传输服务,数据以独立的数据报形式传输。
  • UNIX域套接字_第1张图片

3、UNIX套接字与TCP/IP套接字的不同

UNIX域套接字_第2张图片

4、UNIX域流式套接字通信(TCP)

逻辑如下:

服务器:
(1)socket();
 socket(AF_UNIX, SOCK_STREAM, 0);
 (2)bind();
 /*
 struct sockaddr_un {
 sa_family_t sun_family;               
char        
};
 sun_path[108];            
*/
 struct sockaddr_un serverAddr;
 bzero(&serverAddr, sizeof(serverAddr));
 serverAddr.sun_family = AF_UNIX;
 //serverAddr.sun_sun_path = "./MyClientSockFile";//error:数组名是指针常量!
//做法1:
char *path = "./MyClientSockFile";
 strcpy(serverAddr.sun_path, path);
 //做法2:
//使用sprintf:将数据按照指定格式写入到指定的地址空间中去
sprintf(serverAddr.sun_path, "%s", path);
 (3)listen();
 (4)accept();
 (5)send()/recv();
 (6)close();
客户端:
(1)socket();
 (2)保存服务器的地址信息
(3)connect();
 (4)send()/recv();
 (5)close();

5、UNIX域数据报套接字通信(UDP)

逻辑如下:

服务器:

(1)socket();

(2)bind();

(3)recvfrom()/sendto();

(4)close();

客户端:

(1)socket();

(2)bind();//在UDP这边,客户端必须bind(因为通信时双方必须知道给哪个本地上的套接字文件收发数据)

(3)sendto()/recvfrom(); (4)close();

6、基于UDP的UNIX套接字的代码事例

client.c

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
int main(int argc, const char *argv[])
{
	//创建数据报套接字
	int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
	printf("socket ok!\n");

	//设置客户端地址
	struct sockaddr_un clientAddr;
	bzero(&clientAddr, sizeof(clientAddr));//清空地址结构

	clientAddr.sun_family = AF_UNIX;
	char *path_client = "./MyClientFile";
	sprintf(clientAddr.sun_path, "%s", path_client);

	//绑定客户端的地址信息(必须)
	bind(sockfd, (struct sockaddr *)&clientAddr, sizeof(clientAddr));

	printf("bind ok!\n");
	//设置服务器地址
	struct sockaddr_un serverAddr;
	bzero(&serverAddr, sizeof(serverAddr));//清空地址结构

	serverAddr.sun_family = AF_UNIX;
	char *path_server = "./MyServerFile";
	sprintf(serverAddr.sun_path, "%s", path_server);

	char buf[1024];

	int count;
	while(1)
	{
		memset(buf, 0, sizeof(buf));
		//发送业务给服务器
		printf("请输入业务:\n");
		//fgets(buf, sizeof(buf), stdin);
		scanf("%s", buf);

		sendto(sockfd, buf, strlen(buf), 0, \
				(struct sockaddr *)&serverAddr, sizeof(serverAddr));

		printf("sendto server ok!\n");

		memset(buf, 0, sizeof(buf));
		bzero(&serverAddr, sizeof(serverAddr));
		//处理服务器的应答
		recvfrom(sockfd, buf, sizeof(buf), 0, NULL, NULL);
		printf("服务器应答:[%s]\n", \
				buf);
	}
	//关闭套接字
	close(sockfd);
	return 0;
}

server.c

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
int main(int argc, const char *argv[])
{
	//创建数据报套接字
	int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
	printf("socket ok!\n");


	//设置服务器地址
	struct sockaddr_un serverAddr;
	bzero(&serverAddr, sizeof(serverAddr));//清空地址结构

	serverAddr.sun_family = AF_UNIX;
	char *path_server = "./MyServerFile";
	sprintf(serverAddr.sun_path, "%s", path_server);
	//绑定服务器的地址信息
	if(bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0)
	{
		return -1;
	}
	printf("bind ok!\n");

	//设置客户端地址
	struct sockaddr_un clientAddr;
	bzero(&clientAddr, sizeof(clientAddr));//清空地址结构
	int len = sizeof(clientAddr);
	char buf[1024];

	int count;
	while(1)
	{
		//接收客户端发送的业务
		if((count = recvfrom(sockfd, buf, sizeof(buf), 0, \
						(struct sockaddr *)&clientAddr, &len)) < 0)
		{
			perror("read error");
			return -1;
		}
		else
		{
			buf[count] = '\0';
			printf("recvfrom client 业务[%s]\n", \
					buf);
			//给客户端应答
			sendto(sockfd, "I am udp_server!", strlen("I am udp_server"), 0, \
					(struct sockaddr *)&clientAddr, sizeof(clientAddr));
			printf("sendto  ack_client ok!\n");
		}
	}
	//关闭套接字
	close(sockfd);
	return 0;
}

7、本地间数据通信效率对比

共享内存>UNIX域套接字>消息队列>管道

你可能感兴趣的:(UNIX域套接字)