UDP套接字无法从Go中的服务器读取

时间:2017-11-30 19:06:29

标签: sockets go server dns udp

我正在开发一个快速的DNS客户端,只是为了搞乱但是我在从服务器响应读取时遇到麻烦因为它永远不会到来而且我知道它实际上是因为我有WireShark打开并且它读取包。

以下是代码示例(8.8.8.8是Google DNS,而hex msg是有效的DNS查询):

package main

import (
    "fmt"
    "net"
    "encoding/hex"
    "bufio"
)

func CheckError(err error) {
    if err  != nil {
        fmt.Println("Error: " , err)
    }
}

func main() {

    Conn, err := net.Dial("udp", "8.8.8.8:53")
    CheckError(err)

    defer Conn.Close()
    msg, _ := hex.DecodeString("5ab9010000010000000000001072312d2d2d736e2d68357137646e65650b676f6f676c65766964656f03636f6d0000010001")
    scanner := bufio.NewScanner(Conn)
    buf := []byte(msg)
    _, err1 := Conn.Write(buf)
    if err1 != nil {
        fmt.Println(msg, err1)
    }
    for scanner.Scan() {
        fmt.Println(scanner.Bytes())
    }
}

在这里你有证据证明它实际上到了: WireShark Screen Capture

我睾丸直接从康纳斯读书:

func main() {

    Conn, err := net.Dial("udp", "8.8.8.8:53")
    CheckError(err)

    defer Conn.Close()
    msg, _ := hex.DecodeString("5ab9010000010000000000001072312d2d2d736e2d68357137646e65650b676f6f676c65766964656f03636f6d0000010001")
    buf := []byte(msg)
    _, err1 := Conn.Write(buf)
    if err1 != nil {
        fmt.Println(msg, err1)
    }
    Reader(Conn)
}

func Reader(conn net.Conn) {
    var buf []byte
    for {
        conn.Read(buf)
        fmt.Println(buf)
    }
}

1 个答案:

答案 0 :(得分:1)

您无法在UDP连接周围使用bufio。 UDP不是面向流的协议,因此您需要自己区分各个数据报,并避免部分读取以防止数据丢失。

为了从io.Reader读取,必须分配空间以进行读取,并且需要使用从Read操作返回的字节读取值。您的示例可以简化为:

conn, err := net.Dial("udp", "8.8.8.8:53")
if err != nil {
    log.Fatal(err)
}
defer conn.Close()

msg, _ := base64.RawStdEncoding.DecodeString("WrkBAAABAAAAAAAAEHIxLS0tc24taDVxN2RuZWULZ29vZ2xldmlkZW8DY29tAAABAAE")
resp := make([]byte, 512)

conn.Write(msg)

n, err := conn.Read(resp)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("%q\n", resp[:n])