原创文章,转载请注明出处
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 条评论