0

I am trying to work with UDP and Golang. Because my horizons are microcontrollers, where Go packets (TinyGo) are not completely supported, I need to use as minimal amount of packets as possible. So, I would like to use only the "net" packet, not "net/http". Here (with "net") I can work with UDP using such functions as DialUDP, ListenUDP, ReadToUDP and WriteToUDP. I want to use only them. I saw many samples of working with UDP in Go, showing how to send "Hello" message, but my question is: Is there a way to prepare a data (probably a slice of bytes) containing an "http request" and send it using the mentioned UDP functions? How to prepare such data?

So, is there a way to prepare such request working with UDP and get answers? Or only using "net/http" we can do it?

I mean standard request used to discover SSDP devices (for example network speakers) in a local network, which looks (when using "net/http" packet) like below here. Sending such broadcast message makes all SSDP devices responses, sending back their parameters.

const (
    ssdpSearchMethod = "M-SEARCH"
    ssdpDiscover     = `"ssdp:discover"`
    ssdpUDP4Addr     = "239.255.255.250:1900"
    ssdpAll          = "ssdp:all" 
)

responseBytes := make([]byte, 2048)

req := (&http.Request{
        Method: ssdpSearchMethod,
        Host:   ssdpUDP4Addr,
        URL:    &url.URL{Opaque: "*"}, 
        Header: http.Header{
            "HOST": []string{ssdpUDP4Addr},
            "MX":   []string{strconv.FormatInt(int64(3), 10)},
            "MAN":  []string{ssdpDiscover},
            "ST":   []string{ssdpAll},
        },
    })

n, _, err := httpu.conn.ReadFrom(responseBytes)
2
  • 2
    You can create an HTTP request, write it to a bytes.Buffer, and put the contents of that buffer into a UDP packet. Commented Jan 6 at 19:25
  • Well, as I said, I only want to use "net" Go packet, not the "net/http". Commented Jan 14 at 14:54

1 Answer 1

-1

If i understand it correctly then your example is wrong ssdp is udp so you need to create a UDP package. ssdp send its payload in http Format over udp so you can only use "Net". Your example shows a http request what should not work because it use TCP. So you can create the ssdp request with Sprintf, or just a predifined string because i think it would always be the same, and send the bytes via UDP (net.Dial)

Sign up to request clarification or add additional context in comments.

5 Comments

A little progress thanks to your answer, thanks! But only half of the way - I used as you suggested -> conn, err := net.Dial("udp", "239.255.255.250:1900"), prepared a string containing that SSDP payload and sent it using conn.Write. This works - watching packets on WireShark I see that payload is going and - most importantly - I see that devices in my LAN are answering! Good, but the next operation, n, err := conn.Read(buf) doesn't get those answers (looks like the program hangs on that Read(buf) line... Should the "Read" be done in another way?
Trying to find out the reason I wonder if it is important - probably - I send the "SEARCH" packet to a "generic", standard, "normalized" SSDP address (239.255.255.250:1900), BUT the responses are coming from devices in my LAN, having IP like 192.168.0.0/255 - so maybe this is the reason my conn can not "see" them? How to listen to those "responses"?
Please try conn, err := net.ListenPacket("udp4", ":1900") instead of net.dial, or Look how here its implemented github.com/koron/go-ssdp/blob/main/search.go
Thank you, I saw "koron/go-ssdp" packet earlier, it was one of two which works for me (the second is "huin/goupnp"). Koros is relatively new (10'2023), but uses old ways of multitasking implementation. Multitasking groups are used, joining interfaces are used, a sync packet is used with rlocks etc. In short - a complicated figure is performed to achieve the goal. As I have read, Go has now no need to make those join-groups, it is enough to use just "conn.ReadFromUDP" and "conn.WriteToUDP", with no complication.
I asked ChatGPT and it also recommended the simple version of the implementation, but it's proposaled code also can't see packets returned from SSDP devices. After observing in WireShark responses from SSDP devices in my LAN, with koron, huin and my algorithm - I see small differences between them, so I think I should make a second connection, after sending the "SEARCH" packet from the first connection, because the responses from devices are "incompatible" with the UDP socket of that first connection. I mean, the parameters of those responses (IPs ports, type?) don't fit with the first socket

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.