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

在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:

图片转代码服务由CSDN问答提供 功能建议

如何获取 * net的基础 syscall.Handle 。 Windows上的UDPConn ? 我希望此句柄通过 syscall.SetsockoptInt 设置 IP_MULTICAST_TTL 。 在Linux上,请执行以下操作:

  func setTTL(conn * net.UDPConn,ttl int)错误{
f,err:= conn.File()
如果出现错误 != nil {
 return err 
} 
延迟f.Close()
 fd:= int(f.Fd())
返回syscall.SetsockoptInt(fd,syscall.SOL_IP,syscall.IP_MULTICAST_TTL,ttl  )
} 
   
 
 

但是在Windows上, * net.UDPConn 的< code> File()失败并显示以下信息:

04:24:49 main.go:150:dup:Windows不支持 \ n

,并且在源代码中将其标记为待办事项。 如何获得此手柄? 如果没有,是否还有其他方法可以设置TTL?

Update0

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

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

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
    }
    
    点赞 评论

相关推荐 更多相似问题