【问题标题】:UDP Socket not reading from server in GoUDP Socket 未从 Go 中的服务器读取
【发布时间】:2018-05-14 19:41:10
【问题描述】:

我正在开发一个快速的 dns 客户端,只是为了搞砸但是我在读取服务器响应时遇到了麻烦,因为它永远不会到达,我知道它确实做到了,因为我打开了 WireShark 并且它读取包。

这是代码示例(8.8.8.8 是 Google DNS,十六进制 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

我的测试直接从 conn 读取:

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)
    }
}

【问题讨论】:

  • 直接从连接中读取,在 UDP 连接周围使用缓冲 IO 没有任何意义。
  • @JimB Read 也不起作用
  • 请展示您的尝试。直接从Conn 读取数据报工作正常。
  • @JimB 我刚刚发布了我的尝试
  • 这不是您使用io.Reader 的方式。您需要读取空间,并且需要使用返回的字节数读取值。

标签: sockets go server dns udp


【解决方案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])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-11
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-28
    相关资源
    最近更新 更多