【问题标题】:Google Go Lang - Getting socket id/fd of net/http to use with syscall.BindGoogle Go Lang - 获取 net/http 的套接字 id/fd 以与 syscall.Bind 一起使用
【发布时间】:2015-02-26 21:54:57
【问题描述】:

我正在尝试获取 net/http 请求的套接字 id/fd,以便我可以将它与 syscall.Bind() 一起使用,以将套接字绑定到我的许多公共传出 IPV4 地址之一。

我希望能够选择用于传出请求的 IP 地址。这适用于 Windows。

非常感谢任何帮助。

下面是一些用于 linux 的代码,但我需要获取 http.Client 的套接字 fd 而不是 net.Conn。

func bindToIf(conn net.Conn, interfaceName string) {
    ptrVal := reflect.ValueOf(conn)
    val := reflect.Indirect(ptrVal)
    //next line will get you the net.netFD
    fdmember := val.FieldByName("fd")
    val1 := reflect.Indirect(fdmember)                                   
    netFdPtr := val1.FieldByName("sysfd")                                           
    fd := int(netFdPtr.Int())
    //fd now has the actual fd for the socket
    err := syscall.SetsockoptString(fd, syscall.SOL_SOCKET,
                syscall.SO_BINDTODEVICE, interfaceName)
    if err != nil {
        log.Fatal(err)
    }

}

【问题讨论】:

    标签: sockets http go lang


    【解决方案1】:

    我正在尝试获取 net/http 请求的套接字 id/fd

    http.Requesthttp.Client 都没有可供您获取的套接字。

    您可以通过修改 Transport 来自定义 http.Client 创建 TCP 连接的方式。请参阅 DialDialTLS 函数。

    来自文档:

    Dial 指定用于创建未加密 TCP 连接的拨号功能。如果 Dial 为 nil,则使用 net.Dial。

    您可能对this question 感兴趣,它询问如何使用特定接口拨号。

    你可以像这样设置默认传输:

    http.DefaultTransport.(*http.Transport).Dial = func(network, addr string) (net.Conn, error) {
        d := net.Dialer{LocalAddr: /* your addr here */}
        return d.Dial(network, addr) 
    }
    

    如果您使用 TLS,您需要对 http.DefaultTransport.DialTLS 执行类似的操作。

    【讨论】:

    • 非常感谢@zmb 你的回答很完美,引导我解决问题。虽然我不得不将 http.DefaultTransport.Dial 更改为 http.DefaultTransport.(*http.Transport).Dial
    猜你喜欢
    • 2020-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-24
    • 2019-04-09
    相关资源
    最近更新 更多