4

Consider /var/run/acpid.socket. At any point I can connect to it and disconnect from it. Compare that with nc:

$ nc -l -U ./myunixsocket.sock
Ncat: bind to ./myunixsocket.sock: Address already in use. QUITTING.

nc apparently allows only single-use sockets. Question is then, how do I create a socket analogous to /var/run/acpid.socket, for multiple use and reuse ?

Sergiy Kolodyazhnyy
  • 16,187
  • 11
  • 53
  • 104
  • 2
    The two cases are not equivalent. With `nc` you are trying to have a "server" listening on the socket while something else is already listening to it. In the first case, a single `acpid` instance is listening on the socket. In both cases, multiple clients can write to it. (All this written with an appropriate amount of handwaving). – Kusalananda Sep 21 '18 at 09:27
  • It's not true that `nc` allows only single-use sockets. What's true, is that `nc` is not a real server (it will not `fork` a subprocess to handle a connection, then go back to accepting connections while the child is still running, like eg. the X11 server or `acpid` do); while `nc -l` is handling a connection, it will not `accept()` other connections on the same socket. And this is no different from how `nc -l` works with `tcp` sockets. –  Sep 21 '18 at 12:50
  • @Kusalananda So what do I do to make it equivalent ? I have to keep an extra listening `nc` process just to allow multiple other listeners ? – Sergiy Kolodyazhnyy Sep 21 '18 at 15:12

1 Answers1

4

You do it with the -k option to nc.

-k      Forces nc to stay listening for another connection after its cur-
         rent connection is completed.  It is an error to use this option
         without the -l option.  When used together with the -u option,
         the server socket is not connected and it can receive UDP data-
         grams from multiple hosts.

Example:

$ rm -f /tmp/socket    # unlink the socket if it already exists
$ nc -vklU /tmp/socket # the server
Connection from mack  received!
yes
Connection from mack  received!
yes
...

It's recommended to unlink() the socket after use -- but, in fact, most programs check if it exists and remove it before calling bind() on it; if the socket path exists in the filesystem and you try to bind() to it, you will get an EADDRINUSE error even when no program is using it in any way.

One way to avoid this whole mess on linux is to use "abstract" unix sockets, but they don't seem to be supported by netcat.