C datagram recvfrom unix domain socket

156 views
Skip to first unread message

Gert

unread,
Feb 15, 2020, 10:21:56 AM2/15/20
to golang-nuts
Hi, leaving out a lot of details I basically do this in a C client

fd = socket(PF_UNIX, SOCK_DGRAM, 0)
bind
(fd, (struct sockaddr*) &client, sizeof(struct sockaddr_un)
connect
(fd, (struct sockaddr*) &server, sizeof(struct sockaddr_un)
send
(fd, buff, strlen(buff)+1, 0)
recv
(fd, buff, 8192, 0)

Which means I have a client socket where I receive datagrams and a server socket where I sent datagrams to.

It works in my C client above but having troubles understanding how to talk to the same C server using a Go client instead. This is my attempt


 addr
, err := net.ResolveUnixAddr("unixgram", "client.sock")
 
if err != nil {
   log
.Fatal(err)
 
}

 client
, err := net.ListenUnixgram("unixgram", addr)
 
if err != nil {
   log
.Fatal(err)
 
}
 defer client
.Close()

 server
, err := net.Dial("unixgram", "server.sock")
 
if err != nil {
   log
.Fatal(err)
 
}
 defer server
.Close()

 _
, err = server.Write([]byte("hi"))
 
if err != nil {
   log
.Fatal(err)
 
}

 buf
:= make([]byte, 1024)
 n
, err := client.Read(buf[:])
 
if err != nil {
   println
(err)
 
}
 println
(string(buf[0:n]))

 
if err := os.RemoveAll("client.sock"); err != nil {
   log
.Fatal(err)
 
}


What happens in the Go implementation is that it successfully send a datagram, the server receives it but then the server can't figure out where to send a answer back with a error from the server sendto: `No such file or directory`

This is basically what the the C server code is doing.

recvfrom(fd, buff, 8192, 0, (struct sockaddr*) &client, &len)
sendto
(fd, buff, strlen(buff)+1, 0, (struct sockaddr*) &client, len)

My socket knowledge is limited and https://golang.org/pkg/net/ is overwhelming, if I would make a guess is that de C client shares fd between bind and connect and my Go implementation doesn't ?


Robert Engels

unread,
Feb 15, 2020, 10:26:12 AM2/15/20
to Gert, golang-nuts
See github.com/robaho/go-trader for an example of sending / receiving udp traffic. There’s no reason to use the low level Unix interfaces. 

On Feb 15, 2020, at 9:22 AM, Gert <gert.c...@gmail.com> wrote:


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/644fa128-96c9-47f8-abc5-5fcc19d01e6e%40googlegroups.com.

Robert Engels

unread,
Feb 15, 2020, 10:27:38 AM2/15/20
to Gert, golang-nuts
Sorry. I missed the part about “domain” socket. 

On Feb 15, 2020, at 9:26 AM, Robert Engels <ren...@ix.netcom.com> wrote:



Robert Engels

unread,
Feb 15, 2020, 10:31:00 AM2/15/20
to Gert, golang-nuts
You want to use Recv() and Send() not Read() and Write() in order to get the address information. 

Read() and Write() are for connected sockets and usually streaming. 

On Feb 15, 2020, at 9:27 AM, Robert Engels <ren...@ix.netcom.com> wrote:



Gert

unread,
Feb 15, 2020, 2:53:46 PM2/15/20
to golang-nuts
Thx when looking for Recv() and Send() I found this package https://pkg.go.dev/golang.org/x/sys/unix 

I don't understand how I'm suppose to create a new SockaddrUnix when raw is a private field?

https://play.golang.org/p/fe1f_A92BgI

Also don't know if my strcpy is the way to fill in path?


On Saturday, February 15, 2020 at 4:31:00 PM UTC+1, Robert Engels wrote:
You want to use Recv() and Send() not Read() and Write() in order to get the address information. 

Read() and Write() are for connected sockets and usually streaming. 

On Feb 15, 2020, at 9:27 AM, Robert Engels <ren...@ix.netcom.com> wrote:


Sorry. I missed the part about “domain” socket. 

On Feb 15, 2020, at 9:26 AM, Robert Engels <ren...@ix.netcom.com> wrote:


See github.com/robaho/go-trader for an example of sending / receiving udp traffic. There’s no reason to use the low level Unix interfaces. 
To unsubscribe from this group and stop receiving emails from it, send an email to golan...@googlegroups.com.

Gert

unread,
Feb 15, 2020, 6:25:49 PM2/15/20
to golang-nuts
Another attempt but now I get `socket is already connected`

https://play.golang.org/p/-klJZPnKFRk

robert engels

unread,
Feb 15, 2020, 6:38:24 PM2/15/20
to Gert, golang-nuts
You really should ‘panic on err’ when diagnosing these sort of issues - because I need the full error information.

That being said, if you ‘Connect()’ then many times you can’t use Sendto(), you need to use Send() - or don’t Connect().

When you “Connect” you are connecting the socket which controls the destination for packets.

On Feb 15, 2020, at 5:25 PM, Gert <gert.c...@gmail.com> wrote:

Another attempt but now I get `socket is already connected`

https://play.golang.org/p/-klJZPnKFRk

On Saturday, February 15, 2020 at 8:53:46 PM UTC+1, Gert wrote:
Thx when looking for Recv() and Send() I found this package https://pkg.go.dev/golang.org/x/sys/unix 

I don't understand how I'm suppose to create a new SockaddrUnix when raw is a private field?

https://play.golang.org/p/fe1f_A92BgI

Also don't know if my strcpy is the way to fill in path?

On Saturday, February 15, 2020 at 4:31:00 PM UTC+1, Robert Engels wrote:
You want to use Recv() and Send() not Read() and Write() in order to get the address information. 

Read() and Write() are for connected sockets and usually streaming. 

On Feb 15, 2020, at 9:27 AM, Robert Engels <ren...@ix.netcom.com> wrote:


Sorry. I missed the part about “domain” socket. 

On Feb 15, 2020, at 9:26 AM, Robert Engels <ren...@ix.netcom.com> wrote:


See github.com/robaho/go-trader for an example of sending / receiving udp traffic. There’s no reason to use the low level Unix interfaces. 

On Feb 15, 2020, at 9:22 AM, Gert <gert....@gmail.com> wrote:


Hi, leaving out a lot of details I basically do this in a C client

fd = socket(PF_UNIX, SOCK_DGRAM, 0)
bind
(fd, (struct sockaddr*) &client,sizeof(struct sockaddr_un)

connect
(fd, (struct sockaddr*) &server,sizeof(struct sockaddr_un)

send
(fd, buff, strlen(buff)+1, 0)
recv
(fd, buff, 8192, 0)

Which means I have a client socket where I receive datagrams and a server socket where I sent datagrams to.

It works in my C client above but having troubles understanding how to talk to the same C server using a Go client instead. This is my attempt


 addr
, err :=net.ResolveUnixAddr("unixgram","client.sock")

 
if err != nil {
   log
.Fatal(err)
 
}


 client
, err :=net.ListenUnixgram("unixgram", addr)

 
if err != nil {
   log
.Fatal(err)
 
}
 defer client
.Close()

 server
, err := net.Dial("unixgram","server.sock")
 
if err != nil {
   log
.Fatal(err)
 
}
 defer server
.Close()

 _
, err = server.Write([]byte("hi"))
 
if err != nil {
   log
.Fatal(err)
 
}

 buf 
:= make([]byte, 1024)
 n
, err := client.Read(buf[:])
 
if err != nil {
   println
(err)
 
}
 println
(string(buf[0:n]))

 
if err := os.RemoveAll("client.sock");err != nil {
   log
.Fatal(err)
 
}


What happens in the Go implementation is that it successfully send a datagram, the server receives it but then the server can't figure out where to send a answer back with a error from the server sendto: `No such file or directory`

This is basically what the the C server code is doing.

recvfrom(fd, buff, 8192, 0, (structsockaddr*) &client, &len)
sendto
(fd, buff, strlen(buff)+1, 0,(struct sockaddr*) &client, len)

My socket knowledge is limited and https://golang.org/pkg/net/ is overwhelming, if I would make a guess is that de C client shares fd between bind and connect and my Go implementation doesn't ?



-- 
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golan...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/644fa128-96c9-47f8-abc5-5fcc19d01e6e%40googlegroups.com.

-- 
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/a2c197f9-ceb2-49d7-af4d-f8485a5b69ba%40googlegroups.com.

robert engels

unread,
Feb 15, 2020, 6:45:53 PM2/15/20
to Gert, golang-nuts

robert engels

unread,
Feb 15, 2020, 6:49:25 PM2/15/20
to Gert, golang-nuts
Actually this will be more helpful since it is datagram based:

robert engels

unread,
Feb 15, 2020, 6:58:13 PM2/15/20
to Gert, golang-nuts
Here is some code (I can’t run it because not supported on osx):



Gert

unread,
Feb 15, 2020, 7:20:11 PM2/15/20
to golang-nuts
Your are right about sendto, when I remove the connect part before the sendto, I get the exact same as the very first attempt where the server receives the message but can't send anything back.

Note that as far as I understand 'unixpacket' is for streaming where a open connection get established between server client. I would like a connectionless solution, as in sending a datagram and forget about it and just see if a datagram is fired back to the client. Like the current working C code does.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golan...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golan...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/C23A58B3-9D5A-4009-B0DC-AAA35F884722%40ix.netcom.com.

Gert

unread,
Feb 15, 2020, 7:55:58 PM2/15/20
to golang-nuts
Thanks to the examples you provided I found that in my very first attempt I needed to use `net.DialUnix` instead of `net.Dial`

net.DialUnix("unixgram", &net.UnixAddr{CLIENT_SOCK_FILE, "unixgram"}, &net.UnixAddr{SERVER_SOCK_FILE, "unixgram"})

Now the C server knows where to send a msg back
Reply all
Reply to author
Forward
0 new messages