原创文章,转载请注明出处
https://qiedd.com/
大家都是 HTTPS 了, 就用 DialTLSContext 吧
package main import ( "context" "crypto/tls" "fmt" "io" "log" "net" "net/http" "os" "os/exec" "sort" "time" ) func main() { api, _ := net.LookupIP("api.bilibili.com") results := map[string]*Result{} ch := make(chan struct { addr *net.IP relay time.Duration }) for _, ip := range api { go func(ip net.IP) { // 传入的 IP var addr string if ip.To4() == nil { addr = fmt.Sprintf("[%v]:443", ip.String()) } else { addr = ip.String() + ":443" } // HTTP 客户端 client := &http.Client{ //Transport: &http2.Transport{ // DialTLSContext: func(ctx context.Context, network, address string, cfg *tls.Config) (net.Conn, error) { // dialer := &net.Dialer{ // Timeout: 30 * time.Second, // KeepAlive: 30 * time.Second, // } // // return tls.DialWithDialer(dialer, network, addr, cfg) // }, // TLSClientConfig: tlsConfig(), // DisableCompression: true, //}, Transport: &http.Transport{ DialTLSContext: func(ctx context.Context, network, address string) (net.Conn, error) { dialConn, err := net.Dial(network, addr) if err != nil { return nil, err } config := &tls.Config{ServerName: "api.bilibili.com"} tlsConn := tls.Client(dialConn, config) if err = tlsConn.Handshake(); err != nil { return nil, err } return tlsConn, nil }, }, } // 计时器 ticker := time.NewTicker(time.Second) for range ticker.C { now := time.Now() req, err := http.NewRequest("GET", "https://api.bilibili.com/x/report/click/now", nil) if err != nil { panic(err) } resp, err := client.Do(req) if err != nil { panic(err) } _, _ = io.ReadAll(resp.Body) ch <- struct { addr *net.IP relay time.Duration }{addr: &ip, relay: time.Since(now)} } }(ip) } go func() { for { select { case r := <-ch: result, ok := results[r.addr.String()] if ok { result.TotalRelay = append(result.TotalRelay, r.relay) if len(result.TotalRelay) > 180 { result.TotalRelay = result.TotalRelay[1:] } var totalRelay time.Duration for _, v := range result.TotalRelay { totalRelay += v } result.AverageRelay = totalRelay / time.Duration(len(result.TotalRelay)) result.CurrentRelay = r.relay } else { results[r.addr.String()] = &Result{ Addr: r.addr, CurrentRelay: r.relay, AverageRelay: r.relay, TotalRelay: []time.Duration{}, } } } } }() ticker := time.NewTicker(time.Second) for range ticker.C { clear := exec.Command("clear") clear.Stdout = os.Stdout if err := clear.Run(); err != nil { log.Fatal(err) } var regularResults []*Result for _, v := range results { regularResults = append(regularResults, v) } sort.Slice(regularResults, func(i, j int) bool { return regularResults[i].AverageRelay < regularResults[j].AverageRelay }) for _, v := range regularResults { fmt.Printf("Addr: %v\tAvg Relay:%v\tCurrent Relay: %v \n", v.Addr.String(), v.AverageRelay, v.CurrentRelay) } } } type Result struct { Addr *net.IP CurrentRelay time.Duration AverageRelay time.Duration TotalRelay []time.Duration }
0 条评论