lv7 Embedded Development-Network Programming Development 13 UNIX Domain Sockets

Table of Contents

1 UNIX domain streaming socket

2 UNIX domain datagram socket


1 UNIX domain streaming socket

UNIX domain stream socket is a mechanism for communication between processes on the same host. It does not rely on the network protocol stack, but uses the file system as the basis for communication.

UNIX domain streaming sockets provide reliable, bidirectional, connection-oriented communication. Unlike traditional sockets, UNIX domain sockets do not need to go through the network protocol stack. Data is transferred directly through the buffer in the kernel, so it has the characteristics of low latency and high efficiency.

UNIX domain streaming sockets are widely used for communication between local processes, such as sharing data, synchronizing operations, etc. between multiple processes on the same server. It is an efficient and reliable IPC (inter-process communication) mechanism.

local address

struct sockaddr_un {
  unsigned short sun_family; /* protocol type */
  char sun_path[108]; /* Socket file path */
};

The usage of UNIX domain streaming sockets is basically the same as that of TCP sockets. The difference lies in the protocols and addresses used.

The UNIX domain streaming socket server-side process is as follows:

(1) Create a UNIX domain streaming socket.

(2) Bind the local address (socket file).

(3) Set the monitoring mode.

(4) Receive the client’s connection request.

(5) Send/receive data.

Supplement: Enter man bind in Linux, there is a stream socket sample code below

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

#define MY_SOCK_PATH "/tmp/my_sock_file"
#define LISTEN_BACKLOG 50

#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char *argv[])
{
int sfd, cfd;
struct sockaddr_un my_addr, peer_addr;
socklen_t peer_addr_size;
char buf[BUFSIZ] = {};

sfd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sfd == -1)
handle_error("socket");

memset( & amp;my_addr, 0, sizeof(struct sockaddr_un));
my_addr.sun_family = AF_UNIX;
strncpy(my_addr.sun_path, MY_SOCK_PATH,
sizeof(my_addr.sun_path) - 1);

if (bind(sfd, (struct sockaddr *) &my_addr,
sizeof(struct sockaddr_un)) == -1)
handle_error("bind");
if (listen(sfd, LISTEN_BACKLOG) == -1)
handle_error("listen");

peer_addr_size = sizeof(struct sockaddr_un);
cfd = accept(sfd, (struct sockaddr *) &peer_addr,
&peer_addr_size);
if (cfd == -1)
handle_error("accept");
\t
recv(cfd, buf, BUFSIZ, 0);
printf("%s\\
", buf);

close(cfd);
close(sfd);
    //If you don’t delete the file, an error will occur next time you open it.
remove(MY_SOCK_PATH);
return 0;
}

The UNIX domain streaming socket client process is as follows.

(1) Create a UNIX domain streaming socket.

(2) Specify the server-side address (socket file).

(3) Establish a connection.

(4) Send/receive data.

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

#define MY_SOCK_PATH "/tmp/my_sock_file"

#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char *argv[])
{
int fd;
struct sockaddr_un peer_addr;
char buf[BUFSIZ] = {"Hello World!"};

fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd == -1)
handle_error("socket");

memset( & amp;peer_addr, 0, sizeof(struct sockaddr_un));
peer_addr.sun_family = AF_UNIX;
strncpy(peer_addr.sun_path, MY_SOCK_PATH,
sizeof(peer_addr.sun_path) - 1);

if (connect(fd, (struct sockaddr *) &peer_addr,
sizeof(struct sockaddr_un)) == -1)
handle_error("connect");

printf("%s\\
",buf);
send(fd, buf, strlen(buf), 0);

close(fd);
return 0;
}

2 UNIX domain datagram socket

UNIX domain datagram socket is a mechanism for communication between processes on the same host. Similar to UNIX domain stream sockets, UNIX domain data sockets do not rely on the network protocol stack, but use the file system as the basis for communication.

UNIX domain data sockets provide a connectionless, unreliable method of communication. It communicates using datagrams, each of which is an independent, self-contained message unit. Unlike UNIX domain streaming sockets, UNIX domain data sockets do not require a connection to be established and data can be sent and received directly.

UNIX domain data sockets are suitable for message-oriented communication mode and can be used to implement asynchronous communication between processes, sending and receiving various types of messages, such as commands, status information, etc. It is also commonly used for local inter-process communication, especially when efficient, low latency is required. UNIX domain data sockets are functionally simpler but more efficient than UNIX domain streaming sockets.

For the process of UNIX domain user datagram socket, please refer to UDP socket

The UNIX domain streaming socket server-side process is as follows:

(1) Create a UNIX domain streaming socket.

(2) Bind the local address (socket file).

(3) Send/receive data.

Server

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

#define MY_SOCK_PATH "/tmp/my_sock_file"
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char *argv[])
{
int fd;
struct sockaddr_un my_addr, peer_addr;
socklen_t peer_addr_size;
char buf[BUFSIZ] = {};

fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (fd == -1)
handle_error("socket");

memset( & amp;my_addr, 0, sizeof(struct sockaddr_un));
my_addr.sun_family = AF_UNIX;
strncpy(my_addr.sun_path, MY_SOCK_PATH,
sizeof(my_addr.sun_path) - 1);

if (bind(fd, (struct sockaddr *) &my_addr,
sizeof(struct sockaddr_un)) == -1)
handle_error("bind");

peer_addr_size = sizeof(struct sockaddr_un);
recvfrom(fd, buf, BUFSIZ, 0, (struct sockaddr *) &peer_addr,
&peer_addr_size);
printf("%s\\
",buf);
close(fd);
    //If you don’t delete the file, an error will occur next time you open it.
remove(MY_SOCK_PATH);
return 0;
}

Client

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

#define MY_SOCK_PATH "/tmp/my_sock_file"
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)

int main(int argc, char *argv[])
{
int fd;
struct sockaddr_un peer_addr;
socklen_t peer_addr_size;
char buf[BUFSIZ] = {"Hello World!"};

fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (fd == -1)
handle_error("socket");

memset( & amp;peer_addr, 0, sizeof(struct sockaddr_un));
peer_addr.sun_family = AF_UNIX;
strncpy(peer_addr.sun_path, MY_SOCK_PATH,
sizeof(peer_addr.sun_path) - 1);

peer_addr_size = sizeof(struct sockaddr_un);
printf("%s\\
", buf);
sendto(fd, buf, strlen(buf), 0, (struct sockaddr *) &peer_addr,
peer_addr_size);
close(fd);
    //If you don’t delete the file, an error will occur next time you open it.
remove(MY_SOCK_PATH);
return 0;
}