You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang微控制器环境下,仅用net包通过UDP函数发送HTTP请求可行吗?

不用net/http包,纯UDP实现SSDP M-SEARCH请求

核心结论

完全可以不依赖net/http包,直接手动构造符合HTTP格式的字节切片,通过net包的UDP函数(DialUDP/ListenUDP/WriteToUDP等)发送SSDP发现请求,也能正常接收设备响应。SSDP本质是基于UDP的HTTPU协议,只要遵循HTTP请求的格式规范即可,不需要net/http的序列化逻辑。

手动构造SSDP请求的方法

SSDP的M-SEARCH请求是标准的HTTP格式,结构如下(注意每行结尾必须是\r\n,最后要追加一个空行,即连续两个\r\n):

M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 3
ST: ssdp:all

你可以直接将这个格式拼接成字符串,再转换为[]byte,就得到了可通过UDP发送的请求数据。

TinyGo + net包实现示例

以下是纯net包的实现代码,适配TinyGo环境:

package main

import (
	"log"
	"net"
	"time"
)

const (
	ssdpUDP4Addr     = "239.255.255.250:1900"
	ssdpSearchString = "M-SEARCH * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nMAN: \"ssdp:discover\"\r\nMX: 3\r\nST: ssdp:all\r\n\r\n"
)

func main() {
	// 创建UDP连接
	conn, err := net.DialUDP("udp", nil, &net.UDPAddr{IP: net.ParseIP("239.255.255.250"), Port: 1900})
	if err != nil {
		log.Fatalf("Failed to dial UDP: %v", err)
	}
	defer conn.Close()

	// 设置读取超时,避免无限等待
	err = conn.SetReadDeadline(time.Now().Add(5 * time.Second))
	if err != nil {
		log.Fatalf("Failed to set read deadline: %v", err)
	}

	// 发送SSDP请求
	_, err = conn.Write([]byte(ssdpSearchString))
	if err != nil {
		log.Fatalf("Failed to send SSDP request: %v", err)
	}

	// 接收设备响应
	buf := make([]byte, 2048)
	for {
		n, addr, err := conn.ReadFromUDP(buf)
		if err != nil {
			// 超时退出循环
			if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
				log.Println("Read timeout, no more responses")
				break
			}
			log.Fatalf("Failed to read UDP response: %v", err)
		}
		log.Printf("Received from %s:\n%s", addr, string(buf[:n]))
	}
}

关键说明

  • 手动构造的请求字符串严格遵循HTTP/1.1规范,MAN字段的引号要保留,MX表示设备响应的最大延迟(秒),ST指定搜索目标(这里是所有SSDP设备)。
  • 由于是UDP广播,可能会收到多个设备的响应,所以需要循环读取直到超时。
  • 相比net/http包,这种方式完全不依赖HTTP相关的结构体和序列化逻辑,更适合TinyGo这类对标准库支持有限的环境,减少了不必要的依赖。

内容的提问来源于stack exchange,提问作者Abram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 03:55:19