0

I'm trying to create multicast-style SOCK_DGRAM unix .sock socket where N clients can then connect to and read the messages. OS is GNU/Linux.

Here's my attempt:

package main

import (
    "log"
    "net"
    "os"
    "syscall"
    "time"
)

func main() {
    sockFile := `multicast.sock`

    err := syscall.Mkfifo(sockFile, 0o766|syscall.SOCK_DGRAM|syscall.AF_UNIX)
    if err != nil {
        panic(err)
    }
    defer os.Remove(sockFile) // Remove sock after exit

    fi, err := os.Stat(sockFile)
    if err != nil {
        panic(err)
    }

    addr, err := net.ResolveUnixAddr("unixgram", fi.Name())
    if err != nil {
        panic(err)
    }

    conn, err := net.ListenUnixgram("unixgram", addr)
    if err != nil {
        panic(err)
    }
    defer conn.Close()

    for {
        wb, err := conn.Write([]byte(`hello, world!`))
        if err != nil {
            log.Printf(`err: %v`, err)
            break
        }
        if wb == 0 {
            log.Printf(`we didn't write anything!`)
        }

        time.Sleep(time.Second * 1)
    }
}

Line conn, err := net.ListenUnixgram("unixgram", addr) gives error:

panic: listen unixgram multicast.sock: bind: address already in use

There are no other programs trying to connect to it, so how it is already in use? What's the correct way to listen and create the socket file?

raspi
  • 5,962
  • 3
  • 34
  • 51
  • Why do you assume unix sockets support multicast? They dont. – dimich Jul 11 '22 at 10:45
  • @dimich for example https://stackoverflow.com/questions/51008595/what-is-the-purpose-of-sock-dgram-and-sock-stream-in-the-context-af-unix-sockets/51008665#51008665 and https://stackoverflow.com/questions/61562593/difference-between-unix-domain-sock-dgram-and-sock-seqpacket/61564462#61564462 . Seems to be UDP-like fire-and-forget and one way. ie. multicast to client(s). – raspi Jul 11 '22 at 11:15
  • 1
    `MkFifo` creates a FIFO (a named pipe), which is **not** the same thing as a Unix socket. Your call to `net.ListenUnixgram` attempts to create the socket, but since you've already created a FIFO at that location, you get your `address already in use` panic. – larsks Jul 11 '22 at 11:18
  • 1
    @raspi multicast deliveres data to _all_ subscribed clients. To send data over unix socket you should write to descriptor returned by `accept()` which idenifies a single client. – dimich Jul 11 '22 at 11:32

0 Answers0