Computer Operating System Fundamentals (17) --- Unix domain socket for process synchronization

introduction

This is the seventeenth chapter, Unix domain socket for process synchronization . The previous article introduced the problem of process synchronization through shared memory. This article is another method to achieve process synchronization — Unix domain sockets

Unix domain socket

  • Domain sockets are an advanced method of inter-process communication
  • Unix domain sockets can be used for inter-process communication on the same machine
  • Socket was originally a term used in network communication
  • The domain socket provided by the Unix system provides similar functions to the network socket

I learned earlier that shared memory requires an additional synchronization mechanism to synchronize the communication between multiple processes. Unix domain sockets do not need additional mechanisms to ensure communication between multiple processes (in fact, when we deploy Nginx, we will use unix domain sockets)

How to use Unix domain sockets
: the server is on the left and the client is on the right

Below is a code example, the client and server are connected through a domain socket

Server (server.cpp)

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<strings.h>
#include<string.h>
#include<netinet/in.h>
#include<stdlib.h>

#include<iostream>

//定义域套接字路径
//使用域套接字时,它会在文件系统中创建一个文件,客户端和服务端就是通过这个文件进行连接 
#define SOCKET_PATH "./domainsocket"
//定义消息最大长度
#define MSG_SIZE 2048

int main()
{
	int socket_fd,accept_fd;
	int ret = 0;
	socklen_t addr_len;
	char msg[MSG_SIZE];
	struct sockaddr_un server_addr;

	//1.创建域套接字
	socket_fd = socket(PF_UNIX, SOCK_STREAM, 0);
	if (-1 == socket_fd) {
		std::cout << "Socket create failed" << std::endl;
		return -1;
	}
	//移除已有域套接字路径
	remove(SOCKET_PATH);
	//内存区域设置为0
	bzero(&server_addr, sizeof(server_addr));
	server_addr.sun_family = PF_UNIX;
	strcpy(server_addr.sun_path, SOCKET_PATH);

	//2.绑定域套接字
	std::cout << "Binding socket..." << std::endl;
	ret = bind(socket_fd, (sockaddr *)&server_addr, sizeof(server_addr));

	if (0 > ret) {
		std::cout << "Bind socket failed." << std::endl;
		return -1;
	}

	//3.监听套接字
	std::cout << "Listening socket..." << std::endl;
	ret = listen(socket_fd, 10);//数字为监听连接的大小
	if(-1 == ret) {
		std::cout << "Listen failed" << std::endl;
	}
	std::cout << "Waiting new request." << std::endl;
	accept_fd = accept(socket_fd, NULL, NULL);

	bzero(msg, MSG_SIZE);

	while(true) {
		//4.接收&处理信息
		recv(accept_fd, msg, MSG_SIZE, 0);
		std::cout << "Received message from remote: " << msg << std::endl;
	}

	close(accept_fd);
	close(socket_fd);

	return 0; 
}

Client (client.cpp)

#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<strings.h>
#include<string.h>
#include<netinet/in.h>
#include<stdlib.h>
#include<unistd.h>

#include<iostream>

//定义域套接字路径
//使用域套接字时,它会在文件系统中创建一个文件,客户端和服务端就是通过这个文件进行连接 
#define SOCKET_PATH "./domainsocket"
//定义消息最大长度
#define MSG_SIZE 2048

int main()
{
	int socket_fd;
	int ret = 0;
	char msg[MSG_SIZE];
	struct sockaddr_un serve_addr;

	//1.创建域套接字
	socket_fd = socket(PF_UNIX, SOCK_STREAM, 0);
	if (-1 == socket_fd) {
		std::cout << "Socket create failed" << std::endl;
		return -1;
	}

	//内存区域设置为0
	bzero(&server_addr, sizeof(server_addr));
	server_addr.sun_family = PF_UNIX;
	strcpy(server_addr.sun_path, SOCKET_PATH);

	//2.连接域套接字
	ret = connect(socket_fd, (sockaddr *)&server_addr, sizeof(server_addr));
	if (-1 == ret) {
		std::cout << "Connect socket failed" << std::endl;
		return -1;
	}

	while(true) {
		std::cout << "Input message>>>";
		fgets(msg, MSG_SIZE, stdin);
		//3.发送信息
		ret = send(socket_fd, msg, MSG_SIZE, 0);
	}

	close(socket_fd);

	return 0;
}

Run server.cpp

Run cliet.cpp and send a message

The server receives the message

The domain socket provides a reliable information transfer . Compared with shared memory, it does not need to maintain a mechanism for multiple processes to read the memory space. That is to say, compared to shared memory, domain sockets have more reliability. It can be seen from the code that when the client and the server communicate, no additional tags are needed to manage the synchronization mechanism, and it is simpler to use

to sum up

  • Provides a simple and reliable process communication synchronization service for a single machine
  • It can only be used on a single machine , not across machines (a network socket is required for cross machines)

It is the core competitiveness of a technical person to find the constant in the rapidly changing technology. Unity of knowledge and action, combining theory with practice

Guess you like

Origin blog.csdn.net/self_realian/article/details/107281358