亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

golang 強制 net/http 客戶端使用 IPv4 / IPv6

golang 強制 net/http 客戶端使用 IPv4 / IPv6

Go
DIEA 2023-05-04 16:58:39
我正在使用 go1.11 net/http 并希望檢測域是否僅支持 ipv6。你做了什么?我創建了自己的 DialContext,因為我想檢測域是否僅支持 ipv6。下面的代碼package mainimport (    "errors"    "fmt"    "net"    "net/http"    "syscall"    "time")func ModifiedTransport() {    var MyTransport = &http.Transport{        DialContext: (&net.Dialer{            Timeout:   30 * time.Second,            KeepAlive: 30 * time.Second,            DualStack: false,            Control: func(network, address string, c syscall.RawConn) error {                if network == "ipv4" {                    // I want to  cancel connection here client.Get("http://myexample.com") return a non-nil err.                    return errors.New("you should not use ipv4")                }                return nil            },        }).DialContext,        MaxIdleConns:          100,        IdleConnTimeout:       90 * time.Second,        TLSHandshakeTimeout:   10 * time.Second,        ExpectContinueTimeout: 1 * time.Second,    }    var myClient = http.Client{Transport: MyTransport}    resp, myerr := myClient.Get("http://www.github.com")    if myerr != nil {        fmt.Println("request error")        return     }    var buffer = make([]byte, 1000)    resp.Body.Read(buffer)    fmt.Println(string(buffer))}func main(){    ModifiedTransport();}我現在不知道如何關閉請求,即使我可以進入network == "ipv4".添加Python 可以通過Force requests to use IPv4 / IPv6 來解決這個問題。我不知道如何在 golang 中做到這一點。有人可以幫助我嗎?非常感謝!
查看完整描述

4 回答

?
RISEBY

TA貢獻1856條經驗 獲得超5個贊

傳遞networkControl函數的是tcp4IPv4 連接或tcp6IPv6 連接(如果您正在建立傳出 TCP 連接)。

? ? ? ? // Network and address parameters passed to Control method are not

? ? ? ? // necessarily the ones passed to Dial. For example, passing "tcp" to Dial

? ? ? ? // will cause the Control function to be called with "tcp4" or "tcp6".

(在非 TCP 連接的情況下,其他字符串也是可能的。)

已知網絡是“tcp”、“tcp4”(僅限 IPv4)、“tcp6”(僅限 IPv6)、“udp”、“udp4”(僅限 IPv4)、“udp6”(僅限 IPv6)、“ip” 、“ip4”(僅限 IPv4)、“ip6”(僅限 IPv6)、“unix”、“unixgram”和“unixpacket”。


查看完整回答
反對 回復 2023-05-04
?
弒天下

TA貢獻1818條經驗 獲得超8個贊

哦。我自己解決了這個問題。


我們無法配置強制 ipv6 連接,因為它是硬編碼的


...

if cm.scheme() == "https" && t.DialTLS != nil {

? ? ? ? var err error

? ? ? ? pconn.conn, err = t.DialTLS("tcp", cm.addr())

? ? ? ? if err != nil {

? ? ? ? ? ? return nil, wrapErr(err)

? ? ? ? }

...

我為 transport.go 添加了一個 ipv6only 標志,一個 getTcpString() 并且它有效。


查看完整回答
反對 回復 2023-05-04
?
30秒到達戰場

TA貢獻1828條經驗 獲得超6個贊

這適用于 go1.17.1:


var (

    zeroDialer net.Dialer

    httpClient = &http.Client{

        Timeout: 10 * time.Second,

    }

)


func init() {

    transport := http.DefaultTransport.(*http.Transport).Clone()

    transport.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {

        return zeroDialer.DialContext(ctx, "tcp4", addr)

    }

    httpClient.Transport = transport

}


查看完整回答
反對 回復 2023-05-04
?
慕雪6442864

TA貢獻1812條經驗 獲得超5個贊

我認為即使服務器正在偵聽“tcp6”,使用“tcp”運行 net.Dial 的客戶端也應該可以正常工作——在雙棧設置中。


當我遇到這個問題時,罪魁禍首是 /etc/hosts。它有一個主機條目,映射到 ipv4 地址而不是 ipv6 地址。這導致連接被拒絕。


我的測試示例如下:


客戶端代碼:


package main


import "net"

import "fmt"


func main() {

    conn, err := net.Dial("tcp", "hostname:9876")

    if err != nil {

        fmt.Println("Error in net.Dial", err)

        return

    }


    conn.Close()

    fmt.Println("Successful")

}

服務器代碼:


package main


import "net"

import "fmt"


func main() {

    lis, err := net.Listen("tcp6", ":9876")

    if err != nil {

        fmt.Println("Error in listen", err)

        return

    }


    for {

        _, err := lis.Accept()

        if err != nil {

            fmt.Println("Error in Accept", err)

            return

        }

    }

}

這段代碼應該可以在雙堆棧設置上與干凈的 /etc/hosts 文件一起正常工作。


謝謝。


查看完整回答
反對 回復 2023-05-04
  • 4 回答
  • 0 關注
  • 853 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號