dongzhong5756 2017-11-30 19:06
浏览 17
已采纳

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

I'm developing a fast dns client in go just to mess around with But I'm facing troubles at the time of reading from server responses cause it never arrives and I know it actually did because I have WireShark open and it read the packet.

Here is the code sample(8.8.8.8 is Google DNS and the hex msg is a valid DNS query):

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

Here you have the proof that it actually arrives: WireShark Screen Capture

I've testes reading directly from conn with:

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条回答 默认 最新

  • douzi2333 2017-11-30 20:43
    关注

    You can't use bufio around a UDP connection. UDP is not a stream oriented protocol, so you need to differentiate the individual datagrams yourself, and avoid partial reads to prevent data loss.

    In order to read from an io.Reader, you must have space allocated to read into, and you need to use the bytes read value returned from the Read operation. Your example could be reduced to:

    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
    ", resp[:n])
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?
  • ¥15 乘性高斯噪声在深度学习网络中的应用