Introduction

In the previous article, we talked about Stream Socket and Datagram Socket in Socket. These two Sockets are usually based on tcp and udp protocols for data transmission. Both of these Sockets have a common feature, that is, an IP address and port are required to establish a connection between the client and the server.

So today we will explain a special socket, this socket does not need to use traditional IP addresses and ports, but uses the file system for data interaction between programs, and such sockets can only be used on unix systems. Such a socket is the Unix domain Socket we are going to explain today.

What is Unix domain socket

What is Unix domain Socket? We can see from the name that this socket is related to the unix domain, which means that this socket needs to use some special functions under unix.

Let's consider the commonly used windows system and unix system, what is the biggest difference between them?

In fact, the biggest difference is that everything in the unix operating system can be regarded as a file, including some information about the program running.

So can we directly use the files generated by these programs to interact with data between different programs? The answer is yes. This is the Unix domain Socket we are going to discuss today.

Unix domain Socket can be abbreviated as UDS. Data between different programs can be exchanged at the operating system layer with the help of the file system.

For the program itself, it only needs to read and write the shared socket file, that is to say, different programs exchange data through the socket file.

Like Socket based on IP and port, Unix domain Socket can also be divided into Stream Socket and Datagram Socket.

The most common place we see Unix domain sockets may be docker. As a container technology, docker needs to perform fast data transmission and information exchange with the physical machine. Generally, UDS files end with .socket. Use the following command to find under the /var/run directory:

 find . -name "*.sock"

If you have docker running, you can get the following results:

 ./docker.sock
./docker/libnetwork/6d66a24bfbbfa231a668da4f1ed543844a0514e4db3a1f7d8001a04a817b91fb.sock
./docker/libcontainerd/docker-containerd.sock

You can see that docker communicates through the three sock files above.

Using socat to create Unix Domain Sockets

As mentioned earlier, socat is a versatile tool that can not only create a tcp listening server, but also a udp listening server. Of course, it is not a problem for UDS. Let's take a look at the parameters needed to use socat to create a UDS server:

       unix-listen:<filename>    groups=FD,SOCKET,NAMED,LISTEN,CHILD,RETRY,UNIX
      unix-recvfrom:<filename>  groups=FD,SOCKET,NAMED,CHILD,RETRY,UNIX

Here we need to use the two parameters unix-listen and unix-recvfrom, unix-listen means to create stream-based UDS service, and unix-recvfrom means to create datagram-based UDS.

It can be seen that a file name needs to be passed in after the two parameters, indicating the address of the UDS socket.

We can use it like this:

 socat unix-listen:/tmp/stream.sock,fork /dev/null&
socat unix-recvfrom:/tmp/datagram.sock,fork /dev/null&

Here we use /tmp/datagram.sock to represent this socket information.

The fork parameter indicates that the program continues to run after receiving the package. If fork is not used, the program will automatically exit.

Socat was originally going to be followed by a bi-address. Here we use /dev/null, which means to discard all income information.

After running, we may get the following results:

 [1] 27442
[2] 27450

Indicates that the program has been successfully executed, and the pid of the program is returned.

Use ss command to view Unix domain Socket

Before using the ss command, let's take a look at the two files generated using socat:

 srwxrwxr-x   1 flydean flydean    0 Mar  2 21:58 stream.sock
srwxrwxr-x   1 flydean flydean    0 Mar  2 21:59 datagram.sock

You can see the permissions of these two files, rwx everyone understands, they are read, write and execute permissions. So what is the first s?

The first bit represents the file type, and s represents the socket file.

By extension, there are several other options for this position: p, d, l, s, c, b, and -:

Where p represents a named pipe file, d represents a directory file, l represents a symbolic link file, - represents a normal file, s represents a socket file, c represents a character device file, and b represents a block device file.

Next, we use the ss command to view the UDS service created earlier.

The following parameters need to be used here:

    -n, --numeric       don't resolve service names
   -l, --listening     display listening sockets
   -x, --unix          display only Unix domain sockets

Here we need to use the above 3 options, x means to display UDS, because it is listening, so use the -l parameter, and finally we want to see the specific number instead of being parsed into a service name, so use -n here parameter.

We can try to execute the following command:

 ss -xln

The output will be a lot, we can grep the socket we need as follows:

 ss -xln | grep tmp
u_str  LISTEN     0      5      /tmp/stream.sock 11881005              * 0                  
u_dgr  UNCONN     0      0      /tmp/datagram.sock 11882190              * 0  

u_str represents the UDS stream socket, and u_dg represents the UDS datagram socket.

We can use the stat command to view the specific information of the socket file:

 stat /tmp/stream.sock /tmp/datagram.sock
  File: ‘/tmp/stream.sock’
  Size: 0               Blocks: 0          IO Block: 4096   socket
Device: fd02h/64770d    Inode: 134386049   Links: 1
Access: (0775/srwxrwxr-x)  Uid: ( 1002/    flydean)   Gid: ( 1002/    flydean)
Access: 2022-03-01 22:33:21.533000000 +0800
Modify: 2022-03-01 22:33:21.533000000 +0800
Change: 2022-03-01 22:33:21.533000000 +0800
 Birth: -
  File: ‘/tmp/datagram.sock’
  Size: 0               Blocks: 0          IO Block: 4096   socket
Device: fd02h/64770d    Inode: 134386050   Links: 1
Access: (0775/srwxrwxr-x)  Uid: ( 1002/    flydean)   Gid: ( 1002/    flydean)
Access: 2022-03-01 22:33:22.306000000 +0800
Modify: 2022-03-01 22:33:22.306000000 +0800
Change: 2022-03-01 22:33:22.306000000 +0800
 Birth: -

Connect to Unix domain Socket service using nc

nc is a very powerful tool. In addition to TCP and UDP connections, it can also perform UDS connections. We need to use the following parameters:

   -U, --unixsock             Use Unix domain sockets only
  -u, --udp                  Use UDP instead of default TCP
  -z                         Zero-I/O mode, report connection status only

-U indicates that the connection is a unixsocket. -u means it is a UDP connection.

By default nc uses a TCP connection, so no additional parameters are required.

In addition, we directly establish the connection and do not send any data, so the -z parameter is used here.

First connect to Stream UDS and see:

 nc -U -z /tmp/stream.sock

If no abnormal data is output, the connection is successful.

Then connect to Datagram UDS and see:

 nc -uU -z /tmp/datagram.sock

Similarly, if there is no abnormal data, the Socket connection is successful.

Summarize

In this chapter, we introduced the meaning of Unix Domain Socket in detail, and used some tools in Unix to realize the establishment, detection and connection of UDS. Basically describes the usage of UDS.

This article has been included in http://www.flydean.com/17-unix-domain-socket/

The most popular interpretation, the most profound dry goods, the most concise tutorials, and many tricks you don't know are waiting for you to discover!

Welcome to pay attention to my official account: "Program those things", understand technology, understand you better!


flydean
890 声望433 粉丝

欢迎访问我的个人网站:www.flydean.com