简体   繁体   English

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

[英]Get syscall.Handle from a Go *net.UDPConn on Windows?

How do I obtain the underlying syscall.Handle for a *net.UDPConn on Windows? 如何在Windows上获取*net.UDPConn的底层syscall.Handle I want this handle to set the IP_MULTICAST_TTL via syscall.SetsockoptInt . 我希望这个句柄通过syscall.SetsockoptInt设置IP_MULTICAST_TTL On Linux I do the following: 在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)
}

But on Windows, the implicit dup inside *net.UDPConn 's File() fails with: 但是在Windows上, *net.UDPConnFile()的隐式dup失败了:

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

And in the source code is marked as a to-do. 并在源代码中标记为待办事项。 How can I get this handle? 我怎么能得到这个句柄? Is there some other way to set the TTL if not? 是否还有其他方法可以设置TTL?

Update0 Update0

I've submitted the shortcomings to the Go issue tracker: 我已将缺点提交给Go问题跟踪器:

The short answer is impossible. 简短的回答是不可能的。 But since that isn't an answer you want to hear, I will give you the right way and wrong way to solve the problem. 但既然这不是你想听到的答案,我会以正确的方式和错误的方式来解决问题。

The right way: 正确的方式:

  1. implement dup() for Windows. 为Windows实现dup()
  2. submit to Go as a changeset 提交Go作为变更集
  3. wait for it to be released to use it 等待它被释放以使用它

Obviously the right way has some issues... but I highly recommend doing it. 显然正确的方法有一些问题......但我强烈建议这样做。 Go needs windows developers to fix up these types of serious problems. Go需要Windows开发人员来解决这些类型的严重问题。 The only reason this can't be done in Windows is no one implemented the function 在Windows中无法完成的唯一原因是没有人实现该功能

The wrong way: 错误的方法:

Until the patch you write gets accepted and released, you can fake it through unsafe. 在您编写的补丁被接受并发布之前,您可以通过不安全的方式伪造它。 The way the following code works by mirroring the exact structure of a net.UDPConn . 以下代码的工作方式是镜像net.UDPConn的确切结构。 This included copying over all structs from net that make up a UDPConn . 这包括复制构成UDPConn网络中的所有结构。 Then unsafe is used to assert that the local UDPConn is the same as net's UDPConn . 然后使用unsafe断言本地UDPConn与net的UDPConn相同。 The compiler can not check this and takes your word for it. 编译器无法检查这个并接受你的话。 Were the internals of net to ever change, it would compile but god knows what it would do. 是的内部net永远改变,它会编译,但上帝知道它会怎么做。

All code is untested. 所有代码都未经过测试。

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM