从Windows上的Go*net.UDPConn获取syscall.Handle?

Mat*_*ner 7 sockets windows networking multicast go

如何获得底层syscall.Handle*net.UDPConnWindows上?我想要这个句柄来设置IP_MULTICAST_TTL通道syscall.SetsockoptInt.在Linux上我执行以下操作:

func setTTL(conn *net.UDPConn, ttl int) error {
    f, err := conn.File()
    if err != nil {
        return err
    }
    defer f.Close()
    fd := int(f.Fd())
    return syscall.SetsockoptInt(fd, syscall.SOL_IP, syscall.IP_MULTICAST_TTL, ttl)
}
Run Code Online (Sandbox Code Playgroud)

但在Windows上,隐dup*net.UDPConnFile()失败:

04:24:49 main.go:150:dup:不支持windows

并在源代码中标记为待办事项.我怎么能得到这个句柄?是否还有其他方法可以设置TTL?

Update0

我已将缺点提交给Go问题跟踪器:

Ste*_*erg 12

简短的回答是不可能的.但既然这不是你想听到的答案,我会以正确的方式和错误的方式来解决问题.

正确的方式:

  1. 实施dup()适用于Windows.
  2. 提交Go作为变更集
  3. 等待它被释放以使用它

显然正确的方法有一些问题......但我强烈建议这样做.Go需要Windows开发人员来解决这些类型的严重问题.在Windows中无法完成的唯一原因是没有人实现该功能

错误的方法:

在您编写的补丁被接受并发布之前,您可以通过不安全的方式伪造它.以下代码的工作方式是镜像a的确切结构net.UDPConn.这包括复制构成一个网络的所有结构UDPConn.然后unsafe用于断言本地UDPConn与网络相同UDPConn.编译器无法检查这个并接受你的话.如果内部net变化,它会编译,但上帝知道它会做什么.

所有代码都未经过测试.

package reallyunsafenet

import (
        "net"
        "sync"
        "syscall"
        "unsafe"
)

// copied from go/src/pkg/net/fd_windows.go
type ioResult struct {
        qty uint32
        err error
}

// copied from go/src/pkg/net/fd_windows.go
type netFD struct {
        // locking/lifetime of sysfd
        sysmu   sync.Mutex
        sysref  int
        closing bool

        // immutable until Close
        sysfd       syscall.Handle
        family      int
        sotype      int
        isConnected bool
        net         string
        laddr       net.Addr
        raddr       net.Addr
        resultc     [2]chan ioResult
        errnoc      [2]chan error

        // owned by client
        rdeadline int64
        rio       sync.Mutex
        wdeadline int64
        wio       sync.Mutex
}

// copied from go/src/pkg/net/udpsock_posix.go
type UDPConn struct {
    fd *netFD
}

// function to get fd
func GetFD(conn *net.UDPConn) syscall.Handle {
        c := (*UDPConn)(unsafe.Pointer(conn))
        return c.fd.sysfd
}
Run Code Online (Sandbox Code Playgroud)