7

如何在 Windows 上获取syscall.Handlea的底层?*net.UDPConn我想要这个句柄来设置IP_MULTICAST_TTLvia 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)
}

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

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

并在源代码中标记为待办事项。我怎样才能得到这个手柄?如果没有,还有其他方法可以设置 TTL 吗?

更新0

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

4

1 回答 1

12

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

正确的方式:

  1. 为 Windows实现dup()
  2. 作为变更集提交到 Go
  3. 等待它发布使用它

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

错误的方法:

在您编写的补丁被接受并发布之前,您可以通过 unsafe 伪造它。以下代码通过镜像 a 的确切结构来工作net.UDPConn。这包括从网络复制所有构成UDPConn. thenunsafe用于断言 localUDPConn与 net 的相同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
}
于 2012-07-08T05:16:45.070 回答