猿问

如何使用 go 支持与 UDP 服务器的并发连接

我正在使用我的第一个基本 udp 服务器,我想知道如何支持并发连接?我认为用我的代码一次只能获得一个连接来处理它,用一个 tcp 简单的服务器,事情似乎比这种情况更清楚,抛出一个 goroutine 来处理数据,但在这里我很丢失了,提前致谢。


func main() {

    ListenerUDP("127.0.0.1", 1111)

}


func ListenerUDP(ip string, port int) {

    buffer := make([]byte, 1024)


    log.Println("Listener Started!")

    addr := net.UDPAddr{

        Port: port,

        IP:   net.ParseIP(ip),

    }


    conn, err := net.ListenUDP("udp", &addr)

    if err != nil {

        log.Fatalf("Error Listening:%s\n", err.Error())

        panic(err)

    }

    defer conn.Close()


    for {

        _, remoteAddr, err := conn.ReadFromUDP(buffer[0:])

        if err != nil {

            log.Fatalf("Error:%s\n", err)

        }

        // Process data here? using a > go something()?

        fmt.Printf("Data:%s From:%v\n", buffer, remoteAddr)

    }


}


森栏
浏览 256回答 1
1回答

隔江千里

UDP是一种无连接协议——主机发送数据包而不先建立连接。为了让多个内核并行处理 UDP 数据包,您可能会启动一堆 goroutines,每个 goroutines 执行ReadFromUDP循环:package mainimport (&nbsp; &nbsp; &nbsp; &nbsp; "fmt"&nbsp; &nbsp; &nbsp; &nbsp; "net"&nbsp; &nbsp; &nbsp; &nbsp; "runtime")func listen(connection *net.UDPConn, quit chan struct{}) {&nbsp; &nbsp; &nbsp; &nbsp; buffer := make([]byte, 1024)&nbsp; &nbsp; &nbsp; &nbsp; n, remoteAddr, err := 0, new(net.UDPAddr), error(nil)&nbsp; &nbsp; &nbsp; &nbsp; for err == nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; n, remoteAddr, err = connection.ReadFromUDP(buffer)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // you might copy out the contents of the packet here, to&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // `var r myapp.Request`, say, and `go handleRequest(r)` (or&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // send it down a channel) to free up the listening&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // goroutine. you do *need* to copy then, though,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // because you've only made one buffer per listen().&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("from", remoteAddr, "-", buffer[:n])&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("listener failed - ", err)&nbsp; &nbsp; &nbsp; &nbsp; quit <- struct{}{}}func main() {&nbsp; &nbsp; &nbsp; &nbsp; addr := net.UDPAddr{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Port: 12345,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IP:&nbsp; &nbsp;net.IP{127, 0, 0, 1},&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; connection, err := net.ListenUDP("udp", &addr)&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; panic(err)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; quit := make(chan struct{})&nbsp; &nbsp; &nbsp; &nbsp; for i := 0; i < runtime.NumCPU(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; go listen(connection, quit)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; <-quit // hang until an error}
随时随地看视频慕课网APP

相关分类

Go
我要回答