【问题标题】:Sending UDP packets with gopacket使用 gopacket 发送 UDP 数据包
【发布时间】:2016-07-24 00:32:36
【问题描述】:

我正在尝试向这样的远程主机发送 UDP 数据包

conn, err := net.ListenPacket("ip4:udp", "0.0.0.0")
if err != nil {
    panic(err)
}
ip := &layers.IPv4{
    SrcIP:    saddr,
    DstIP:    dip,
    Protocol: layers.IPProtocolUDP,
}
udp := &layers.UDP{
    SrcPort: layers.UDPPort(sport),
    DstPort: layers.UDPPort(us.Port),
}
udp.SetNetworkLayerForChecksum(ip)
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{
    ComputeChecksums: true,
    FixLengths:       true,
}
if err := gopacket.SerializeLayers(buf, opts, udp); err != nil {
    fmt.Printf("%v", err)
}
if _, err := us.Conn.WriteTo(buf.Bytes(), &net.IPAddr{IP: dip}); err != nil {
    panic(err)
}

// reading
for {
    buf2 := make([]byte, 4096)
    n, addr, err := us.Conn.ReadFrom(buf2)
    if err != nil {
        fmt.Printf("%v", err)
    }
    if addr.String() == dip.String() {
        fmt.Printf("Got a reply")
    }
}

但这在使用read ip4 0.0.0.0: i/o timeout 读取数据包时总是出错。当我 tcpdump 时,我看到数据包被发送出去,一个 UDP 响应在端口 53 上返回,其他的都是 ICMP。为什么我的代码无法读取这些数据包?

【问题讨论】:

    标签: networking go network-programming gopacket


    【解决方案1】:

    我不是 Go 专家,但您似乎必须使用函数 net.ListenUDP 并指定绑定 UDP 套接字的端口。然后您使用该连接(从 ListeUDP 获得)从那里读取。我假设您在“运动”中指定端口 53。

    这里有一个简单的客户端和服务器示例:https://varshneyabhi.wordpress.com/2014/12/23/simple-udp-clientserver-in-golang/

    【讨论】:

      【解决方案2】:

      您在示例中混合了两种不同的 UDP 数据包创建方法。你应该只使用一个。

      第一种方法是使用 Go 应用程序“net”模块来准备和发送 UDP 数据包。这是一种常见的方式,并且您会以最常见的方式使用它。

      第二种方法使用谷歌特殊的“gopacket”模块来准备RAW网络数据包。这是黑客检查硬件或实现特殊协议并模拟某些特定协议栈的方法。这是创建特殊实用程序和测试应用程序的唯一专家方法。

      如果您创建新硬件并尝试与此设备交互,您可以使用 gopakcet,或者如果您简单地创建软件应用程序,您应该使用 net package。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-09-15
        • 1970-01-01
        • 2016-10-26
        • 2020-01-20
        • 1970-01-01
        • 2012-12-07
        • 1970-01-01
        相关资源
        最近更新 更多