使用struct union

时间:2017-05-28 09:20:49

标签: networking go

我试图使用GO在Windows上调用TransmitPackets函数 目标是能够通过一个系统调用发送多个数据包(无法通过WSASend [它发送分段的IP数据包]来实现)。

我的代码恐慌

panic: write udp 192.168.1.26:51817->8.8.8.8:8000: transmitpackets: An invalid argument was supplied.
goroutine 1 [running]:
main.main()
    c:/Users/amit/dev/go/src/rio/main.go:26 +0x210
exit status 2
Process exiting with code: 1

这是我的测试代码

package main

import (
    "math/rand"
    "net"
)

func main() {
    raddr, err := net.ResolveUDPAddr("udp", "8.8.8.8:8000")
    if err != nil {
        panic(err)
    }
    con, err := net.DialUDP("udp", nil, raddr)
    if err != nil {
        panic(err)
    }

    packets := make(net.Buffers, 10)
    for i := 0; i < len(packets); i++ {
        packets[i] = make([]byte, 1400)
        rand.Read(packets[i])
    }

    _, err = con.WriteMultiple(packets)
    if err != nil {
        panic(err)
    }

}

这是我对TransmitPackets的调用:

type TransmitPacketsElement struct {
    dwElFlags   uint32
    cLength     uint32
    pBuffer     unsafe.Pointer
    nFileOffset uint64
    hFile       uintptr
}

func transmitPackets(s Handle, bufs [][]byte, overlapped *Overlapped) (err error) {
    var maxPacketLen = 0
    tpElements := make([]TransmitPacketsElement, len(bufs))
    for i, tpElement := range tpElements {
        buffer := bufs[i]
        if len(buffer) > maxPacketLen {
            maxPacketLen = len(buffer)
        }
        tpElement.cLength = uint32(len(buffer))
        tpElement.dwElFlags = uint32(uint32(TP_ELEMENT_MEMORY) | uint32(TP_ELEMENT_EOP))
        tpElement.pBuffer = unsafe.Pointer(&buffer[0])
    }
    r1, _, e1 := Syscall6(transmitPacketsFunc.addr, 6, uintptr(s), uintptr(unsafe.Pointer(&tpElements[0])), uintptr(uint32(len(tpElements))), uintptr(uint32(maxPacketLen)), uintptr(unsafe.Pointer(overlapped)), 0)
    if r1 == 0 {
        if e1 != 0 {
            err = error(e1)
        } else {
            err = EINVAL
        }
    }
    return
}

您可以在github

上修改后的go 1.8.3源代码中看到完整的实现

0 个答案:

没有答案