package main
import (
"fmt"
"net"
"log"
"os"
)
const MAX_MTU int = 1024 * 64
func main() {
// 创建监听
file, err := os.Create("/data/flume-agent/log/go_udp.log")
if err != nil {
log.Fatalln("fail to create go_udp.log file!")
}
logger := log.New(file, "", log.LstdFlags|log.Llongfile)
logger.Println("started udp server")
socket, err := net.ListenUDP("udp4", &net.UDPAddr{
IP: net.IPv4(0, 0, 0, 0),
Port: 5122,
})
if err != nil {
logger.Println("监听失败!", err)
return
}
defer socket.Close()
for {
// 读取数据
data := make([]byte, MAX_MTU)
_, remoteAddr, err := socket.ReadFromUDP(data)
if err != nil {
fmt.Println("读取数据失败!", err)
continue
}
fmt.Printf("%s %s\n",remoteAddr.IP,data)
// 发送数据
/*
senddata := []byte("receive success!")
_, err = socket.WriteToUDP(senddata, remoteAddr)
if err != nil {
logger.Println("发送数据失败!", err)
return
}
*/
}
}
以上代码测试一下似乎是同步的,压测效率低的可怜,而且数据丢失严重
对go的一些web框架都是多线程异步高并发,请问udp这里如何实现?
折腾最后这样吧:
package main
import (
"net"
"log"
"os"
"fmt"
)
type Data struct{
C string
D *net.UDPAddr
}
const MAX_MTU int = 1024 * 64
var path string = "/data/flume-agent/log/go_xg_udp.log"
func main() {
// 创建监听
log.SetFlags(0)
file, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666)
if err != nil {
log.Fatalln("fail to create go_udp.log file!")
}
logger := log.New(file, "", log.LstdFlags|log.Llongfile)
logger.Println("started udp server")
socket, err := net.ListenUDP("udp4", &net.UDPAddr{
IP: net.IPv4(0, 0, 0, 0),
Port: 5141,
})
if err != nil {
logger.Println("监听失败!", err)
return
}
defer socket.Close()
c := make(chan Data, 1024) // 带缓冲的通道
for {
// 读取数据
data := make([]byte, MAX_MTU)
read, remoteAddr, err := socket.ReadFromUDP(data)
if err != nil {
logger.Println("读取数据失败!", err)
continue
}
go sets(string(data[:read]), remoteAddr, c)
select {
case k:=<-c:
fmt.Println(k.D.IP,k.C)
}
}
}
func sets(k string, remoteAddr *net.UDPAddr, c chan Data){
c<-Data{k, remoteAddr}
}
原来udp启动之后,后面的并发不并发自己随便写就可以了,还是可以走到的
参考:https://tonychyi.wetofu.top/2015/11/25/async-udp-server-using-go/
#1
更多评论
<pre><code>package main
import (
"net"
"log"
"os"
"fmt"
)
type Data struct{
C string
D *net.UDPAddr
}
const MAX_MTU int = 1024 * 64
var path string = "/data/flume-agent/log/go_xg_udp.log"
func main() {
// 创建监听
log.SetFlags(0)
file, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666)
if err != nil {
log.Fatalln("fail to create go_udp.log file!")
}
logger := log.New(file, "", log.LstdFlags|log.Llongfile)
logger.Println("started udp server")
socket, err := net.ListenUDP("udp4", &net.UDPAddr{
IP: net.IPv4(0, 0, 0, 0),
Port: 5141,
})
if err != nil {
logger.Println("监听失败!", err)
return
}
defer socket.Close()
c := make(chan Data, 1024) // 带缓冲的通道
for {
// 读取数据
data := make([]byte, MAX_MTU)
read, remoteAddr, err := socket.ReadFromUDP(data)
if err != nil {
logger.Println("读取数据失败!", err)
continue
}
go sets(string(data[:read]), remoteAddr, c)
select {
case k:=<-c:
fmt.Println(k.D.IP,k.C)
}
}
}
func sets(k string, remoteAddr *net.UDPAddr, c chan Data){
c<-Data{k, remoteAddr}
}
</code></pre>
折腾这样吧,发现之前发的没有用markdown标注,不好意思
原来udp启动之后,后面的并发不并发自己随便写就可以了,还是可以走到的
[参考:](https://tonychyi.wetofu.top/2015/11/25/async-udp-server-using-go/)https://tonychyi.wetofu.top/2015/11/25/async-udp-server-using-go/
#2