7

Windowsの の基盤syscall.Handleを取得するにはどうすればよいですか? このハンドルでvia*net.UDPConnを設定したい。Linuxでは、次のことを行います。IP_MULTICAST_TTLsyscall.SetsockoptInt

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 では、暗黙のdupinsideは次*net.UDPConnのようにFile()失敗します。

04:24:49 main.go:150: dup: Windows ではサポートされていません

そして、ソース コードでは、to-do としてマークされています。このハンドルを取得するにはどうすればよいですか? そうでない場合、TTLを設定する他の方法はありますか?

Update0

欠点を Go イシュー トラッカーに提出しました。

4

1 に答える 1

12

短い答えは不可能です。しかし、それはあなたが聞きたい答えではないので、問題を解決するための正しい方法と間違った方法を教えます.

正しい方法:

  1. Windows 用に実装dup()します。
  2. 変更セットとして Go に送信する
  3. リリースされるのを待って使用してください

明らかに正しい方法にはいくつかの問題があります...しかし、私はそれを行うことを強くお勧めします. Go では、この種の深刻な問題を修正するために Windows 開発者が必要です。これが Windows で実行できない唯一の理由は、誰も関数を実装していないことです

間違った方法:

あなたが書いたパッチが受け入れられてリリースされるまでは、unsafe を介して偽装することができます。の正確な構造をミラーリングすることにより、次のコードが機能する方法net.UDPConn。これには、a を構成する net からのすべての構造体のコピーが含まれUDPConnます。次に、 localが net と同じでunsafeあることをアサートするために使用されます。コンパイラはこれをチェックできず、あなたの言葉を受け入れます。toの内部が変更された場合、それはコンパイルされますが、神はそれが何をするかを知っています。UDPConnUDPConnnet

すべてのコードはテストされていません。

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 に答える