Golang如何实现异步Udp Server接入数据

arterforyou · 2017-12-04 10:45:33 · 2393 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2017-12-04 10:45:33 的主题,其中的信息可能已经有所发展或是发生改变。

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这里如何实现?


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2393 次点击  
加入收藏 微博
2 回复  |  直到 2017-12-04 14:21:54
arterforyou
arterforyou · #1 · 7年之前

折腾最后这样吧: 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/

arterforyou
arterforyou · #2 · 7年之前

<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/

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传