我正在尝试编写一个小的http下载程序包,该程序包可以允许在创建时控制tcp套接字选项,而我确实对定义套接字选项的可能性感到困惑。 据我了解,在包 net 结构 Dialer 的1.11版本中,添加了接口 Control ,该接口应允许定义此类选项,但我在我要实现的上下文中找不到任何有关用法的有效示例。
dialer := &net.Dialer{
Timeout: 5 * time.Second,
Deadline: time.Time{},
LocalAddr: nil,
DualStack: false,
FallbackDelay: 0,
KeepAlive: 0,
Resolver: nil,
Control: controlOnConnectionSetup,
}
// set client
client := http.Client{
Transport: &http.Transport{
Proxy: nil,
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialer.DialContext(ctx, "tcp", addr)
},
Dial: nil,
DialTLS: nil,
TLSClientConfig: nil,
TLSHandshakeTimeout: 0,
DisableKeepAlives: false,
DisableCompression: false,
MaxIdleConns: 0,
MaxIdleConnsPerHost: 0,
MaxConnsPerHost: 0,
IdleConnTimeout: 0,
ResponseHeaderTimeout: 0,
ExpectContinueTimeout: 0,
TLSNextProto: nil,
ProxyConnectHeader: nil,
MaxResponseHeaderBytes: 0,
},
CheckRedirect: nil,
Jar: nil,
Timeout: 3,
}
和 cotrol 函数的代码(不起作用,它只是从示例中复制的,在该示例中我找不到对 fd 变量的任何提及):
func controlOnConnectionSetup(network string, address string, c syscall.RawConn) error {
var operr error
fn := func(s uintptr) {
handle := syscall.Handle(fd)
operr = syscall.SetsockoptInt(handle, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
if operr != nil {
return
}
}
if err := c.Control(fn); err != nil {
return err
}
if operr != nil {
return operr
}
return nil
}
如果有人能告诉我我在做什么错,或者至少提供有关如何在tcp连接中控制套接字参数的示例,我将不胜感激。
答案 0 :(得分:2)
您应将func(s uintptr)
更改为func(fd uintptr)
,例如:
func myControl(network, address string, c syscall.RawConn) error {
return c.Control(func(fd uintptr) {
// set the socket options
err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_IP, syscall.IP_TTL, 66)
if err != nil {
log.Println("setsocketopt: ", err)
}
})
}