Is there any purpose for the `bind ()` unix processes of a socket client socket?

When using AF_UNIX(unix domain sockets), is there any application to call bind()in a process that never calls listen()?

In my lecture on system and laboratory programming, we are tasked with bind()invoking a unix domain socket on the client processes. Is there any documented, undocumented, or practical application for calling bind in a unix domain socket process for the client only? In my understanding, it bind()creates a special socket file, which is responsible for the server process. Is it correct?

Here is a sample code based on what concepts are discussed in the class:

server.c

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>

int main() {
    int s0, s1;
    struct sockaddr sa0 = {AF_UNIX, "a"};

    s0 = socket(AF_UNIX, SOCK_STREAM, 0);

    bind(s0, &sa0, sizeof(sa0) + sizeof("a"));
    listen(s0, 1);
    for (;;) {
        s1 = accept(s0, NULL, NULL);
        puts("connected!");
        for (;;) {
            char text[1];
            ssize_t n = read(s1, &text, sizeof(text));
            if (n < 1) {
                break;
            }
            putchar(text[0]);
        }
        close(s1);
    }
    close(s0);
    unlink("a");
    return 0;
}

client.c

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>

int main() {
    int s0;
    struct sockaddr sa0 = {AF_UNIX, "b"};
    struct sockaddr sa1 = {AF_UNIX, "a"};
    socklen_t sa1_len;

    s0 = socket(AF_UNIX, SOCK_STREAM, 0);
    bind(s0, &sa0, sizeof(sa0) + sizeof("b")); // What does this do??
    connect(s0, &sa1, sizeof(sa1) + sizeof("b"));
    for (;;) {
        int c = fgetc(stdin);
        if (c == EOF) {
            break;
        }
        write(s0, &c, sizeof(c));
    }
    close(s0);
    unlink("b");
    return 0;
}
+4
3

bind() , SOCK_STREAM, bind() SOCKET. .

:

UNIX :

#define UNIX_PATH_MAX    108

struct sockaddr_un {
    sa_family_t sun_family;               /* AF_UNIX */
    char        sun_path[UNIX_PATH_MAX];  /* pathname */
};

:

  • pathname: UNIX , bind (2). getockname (2), getpeername (2) accept (2), offsetof (struct sockaddr_un, sun_path) + strlen (sun_path) + 1 sun_path .

  • unnamed: , bind (2), . , , socketpair (2) . getockname (2), getpeername (2) accept (2), sizeof (sa_family_t), sun_path .

  • abstract: , sun_path [0] ('\ 0'). sun_path, . ( .) . getockname (2), getpeername (2) accept (2), return addrlen , sizeof (sa_family_t) (.. 2), (addrlen

  • sizeof (sa_family_t)) sun_path. - Linux.

, , ( unlink (2)). UNIX; , , , .


:

  • bind() .
  • bind() "a" "b"
  • bind(s0, &sa0, sizeof(sa0) + sizeof("b")); undefined; bind(), &sa0. bind(s0, &sa0, sizeof sa0);
  • bind() (Linux, AF_UNIX) ; , unlink() remove().
+3

man bind :

   When  a  socket  is  created  with socket(2), it exists in a name space
   (address family) but has no address assigned to it.  bind() assigns the
   address  specified  by  addr  to  the  socket  referred  to by the file
   descriptor sockfd.  addrlen  specifies  the  size,  in  bytes,  of  the
   address structure pointed to by addr.  Traditionally, this operation is
   called "assigning a name to a socket".

   It is normally necessary to assign a local address using bind()  before
   a SOCK_STREAM socket may receive connections (see accept(2)).
+1

Calling bind()in the juice of a Unix domain, without the intention of ever calling accept(), is a very useful way to ensure that only one copy of the process is executed. This is much more reliable than relying on a process name, since binaries can be copied and run under a different name.

Cleaning at abnormal termination ( SIGSEGVwhich is the goal kill -9 ...) is a problem. since the socket will not be deleted if your application does not execute it in the signal handler.

+1
source

Source: https://habr.com/ru/post/1690404/


All Articles