已经写好了,二进制文件也放出来了,在github开源,详情:https://www.nodeseek.com/post-24956-1
已经写好了,二进制文件也放出来了,在github开源,详情:https://www.nodeseek.com/post-24956-1
已经写好了,二进制文件也放出来了,在github开源,详情:https://www.nodeseek.com/post-24956-1
最近被香港BGP和日本IIJ折腾的头痛欲裂,既然tcping才比较真实,于是想上tcping监控,结果发现都得装一堆东西,还不如自己手动写一个tcping程序。于是就写了下面的这个。
使用教程
- 如果是IP,那就直接IP地址 端口,中间空格隔开就好了
- 如果是域名,也是域名 端口,中间空格隔开,默认使用IPv4地址,如果需要IPv6,则加
-version v6之后再空格隔开,并继续添加域名 端口,中间空格隔开。 - 每秒钟tcping一次,
以下为例子,编译的时候,使用go build -o tcping /path/to/main.go
tcping IPv4 Port
tcping 1.1.1.1 80 # tcping 一下cloudflare的1.1.1.1
tcping IPv6 Port
tcping 2606:4700:4700::1111 80 # tcping 一下cloudflare的2606:4700:4700::1111
tcping domain Port
tcping nodeseek.com 443
tcping -version v6 domain Port
tcping -version v6 nodeseek.com 443
源码如下:
package main
import (
"flag"
"fmt"
"net"
"os"
"os/signal"
"syscall"
"time"
)
func isValidIP(ip string) bool {
addr := net.ParseIP(ip)
return addr != nil
}
func isValidPort(port string) bool {
_, err := net.LookupPort("tcp", port)
return err == nil
}
func resolveIPAddress(ip string) (ipv4, ipv6 net.IP, err error) {
ips, err := net.LookupIP(ip)
if err != nil {
return nil, nil, err
}
for _, ip := range ips {
if ip.To4() != nil {
ipv4 = ip
} else {
ipv6 = ip
}
}
return ipv4, ipv6, nil
}
func main() {
// Define the version flag
versionFlag := flag.String("version", "v4", "IP version (v4 or v6)")
// Parse the command line flags
flag.Parse()
// Check if there are enough positional arguments
if flag.NArg() != 2 {
fmt.Println("Usage: tcping [-version v4|v6] ")
os.Exit(1)
}
ip := flag.Arg(0)
port := flag.Arg(1)
version := *versionFlag
// Resolve the IP address or domain name
ipv4, ipv6, err := resolveIPAddress(ip)
if err != nil {
fmt.Printf("Failed to resolve %s: %s
", ip, err)
os.Exit(1)
}
// Only print the resolved IP if the input is a domain name
if net.ParseIP(ip) == nil {
if ipv4 != nil {
fmt.Printf("Domain %s was resolved as [%s] (IPv4)
", ip, ipv4)
}
if ipv6 != nil {
fmt.Printf("Domain %s was resolved as [%s] (IPv6)
", ip, ipv6)
}
}
// Select the IP version to use
var selectedIP net.IP
if version == "v4" && ipv4 != nil {
selectedIP = ipv4
} else if version == "v6" && ipv6 != nil {
selectedIP = ipv6
} else {
fmt.Println("Invalid IP version or IP address.")
os.Exit(1)
}
if !isValidIP(selectedIP.String()) {
fmt.Println("Invalid IP address.")
os.Exit(1)
}
if !isValidPort(port) {
fmt.Println("Invalid port number.")
os.Exit(1)
}
// If the IP is IPv6, add [] around it
if selectedIP.To4() == nil {
ip = fmt.Sprintf("[%s]", selectedIP)
} else {
ip = selectedIP.String()
}
address := fmt.Sprintf("%s:%s", ip, port)
fmt.Printf("Pinging %s...
", address)
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
mainLoop:
for {
select {
case <-sigChan:
fmt.Println("
TCPing stopped.")
break mainLoop
default:
start := time.Now()
conn, err := net.Dial("tcp", address)
elapsed := time.Since(start)
// Convert the elapsed time to milliseconds without decimals
elapsed = elapsed.Round(time.Millisecond)
if err != nil {
fmt.Printf("Failed to connect to %s: %s
", address, err)
} else {
conn.Close()
fmt.Printf("tcping %s in %s
", address, elapsed)
}
time.Sleep(time.Second) // Wait for 1 second before the next ping
}
}
}

技术佬
api高手
怎么玩