go - 去 udp 连接拨号一次,然后发送很多
问题描述
请考虑下面的代码,它是服务的简化版本。我发起一个不。goroutines 在其生命周期中根据需要,并且当他们开始做事时,他们需要将 udp 消息发送到设定的目的地。
package main
import (
"fmt"
"log"
"net"
"time"
)
const (
udp_dest = "192.168.1.200:514"
)
func main() {
fmt.Println("Hello")
message := "this is a test"
log_message(&message)
go worker(1)
go worker(2)
go worker(3)
go worker(4)
time.Sleep(3009 * time.Second)
}
func log_message(message *string) {
RemoteAddr, err := net.ResolveUDPAddr("udp", udp_dest)
if err != nil {
//fmt.Println("Err, net.ResolveUDPAddr", err)
return
}
conn, err := net.DialUDP("udp", nil, RemoteAddr)
if err != nil {
return
}
udp_message := fmt.Sprintf("<30> %s", *message)
Bytes, _ := conn.Write([]byte(udp_message))
log.Printf("Sent %d Bytes to %s\n", Bytes, udp_dest)
}
func worker(tag int) {
i := 0
for {
worker_message := fmt.Sprintf("Some message from worker%d, loop: %d", tag, i)
log_message(&worker_message)
// do some work..
time.Sleep(300 * time.Second)
i += 1
}
}
在 mylog_message
中,每次它被调用时,我们都在调用net.DialUDP
它,我觉得这很浪费。我尝试尝试使用全局变量&net.UDPConn
等,但无法开始工作。
请展示如何实现/优化这一点?只有一个 UDP 目的地,我希望守护进程Dial
在其启动时执行一次,然后Write
根据需要执行一次。
谢谢!
这是我到目前为止得到的:
package main
import (
"fmt"
"log"
"net"
"time"
)
const (
udp_dest = "192.168.1.200:514"
)
var (
myconn *net.UDPConn
)
func main() {
fmt.Println("Hello")
message := "this is a test"
log_message(&message)
go worker(1)
go worker(2)
go worker(3)
go worker(4)
time.Sleep(3009 * time.Second)
}
func log_message(message *string) {
if myconn == nil {
fmt.Println("Setting up myconn!")
RemoteAddr, err := net.ResolveUDPAddr("udp", udp_dest)
if err != nil {
//fmt.Println("Err, net.ResolveUDPAddr", err)
return
}
myconn, err = net.DialUDP("udp", nil, RemoteAddr)
if err != nil {
return
}
}
udp_message := fmt.Sprintf("<30> %s", *message)
Bytes, _ := myconn.Write([]byte(udp_message))
log.Printf("Sent %d Bytes to %s\n", Bytes, udp_dest)
}
func worker(tag int) {
i := 0
for {
worker_message := fmt.Sprintf("Some message from worker%d, loop: %d", tag, i)
log_message(&worker_message)
// do some work..
time.Sleep(10 * time.Second)
i += 1
}
}
解决方案
你快到了。将设置代码移动到一个函数并在启动 goroutine 之前调用它。
func main() {
if err := setupLog(); err != nil {
log.Fatal(err)
}
fmt.Println("Hello")
... same as before
}
func setupLog() error {
fmt.Println("Setting up myconn!")
RemoteAddr, err := net.ResolveUDPAddr("udp", udp_dest)
if err != nil {
return err
}
myconn, err = net.DialUDP("udp", nil, RemoteAddr)
return err
}
func log_message(message *string) {
udp_message := fmt.Sprintf("<30> %s", *message)
Bytes, _ := myconn.Write([]byte(udp_message))
log.Printf("Sent %d Bytes to %s\n", Bytes, udp_dest)
}
问题中的代码不起作用,因为myconn
.
推荐阅读
- c# - 使用 BinaryReader/BinaryWriter 从/向同一行读取和写入
- c++ - 从 ifstream 中识别 String 或 Int
- c# - XML 中的 API 响应编码错误,如何更正/转换字符串?
- google-play - Play store error: can't install app再试一次,还是不行,看看常见的解决方法
- kubernetes - Kubectl JSONPath 表达式根据当前上下文获取 cluster.server 属性
- javascript - 比较两个数组,如果 id 相等则禁用单个元素
- python - 是否有通过对其他列进行一些计算来将列添加到数据集的最快方法?
- amazon-web-services - AWS 使用 Bamboo 删除 ECS 服务 - 服务无法停止
- html - 有没有办法在谷歌图表上绘制一条横跨散点的水平线?
- c++ - C ++中的传递符号可见性