doufubu2518 2012-07-03 20:55
浏览 242
已采纳

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

How do I obtain the underlying syscall.Handle for a *net.UDPConn on Windows? I want this handle to set the IP_MULTICAST_TTL via syscall.SetsockoptInt. On Linux I do the following:

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:

04:24:49 main.go:150: dup: not supported by 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?

Update0

I've submitted the shortcomings to the Go issue tracker:

  • 写回答

1条回答 默认 最新

  • dongshi1914 2012-07-08 05:16
    关注

    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.
    2. submit to Go as a changeset
    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. The only reason this can't be done in Windows is no one implemented the function

    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. This included copying over all structs from net that make up a UDPConn. Then unsafe is used to assert that the local UDPConn is the same as net's 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.

    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
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 MATLAB怎么通过柱坐标变换画开口是圆形的旋转抛物面?
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题
  • ¥15 Visual Studio问题
  • ¥20 求一个html代码,有偿