4 回答
TA贡献1856条经验 获得超5个赞
传递network
给Control
函数的是tcp4
IPv4 连接或tcp6
IPv6 连接(如果您正在建立传出 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”。
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() 并且它有效。
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
}
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 文件一起正常工作。
谢谢。
- 4 回答
- 0 关注
- 620 浏览
添加回答
举报