我写了一个很好的tcping程序,可是论坛不能带附件,那就放源码吧

已经写好了,二进制文件也放出来了,在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程序。于是就写了下面的这个。

使用教程

  1. 如果是IP,那就直接IP地址 端口,中间空格隔开就好了
  2. 如果是域名,也是域名 端口,中间空格隔开,默认使用IPv4地址,如果需要IPv6,则加-version v6 之后再空格隔开,并继续添加域名 端口,中间空格隔开。
  3. 每秒钟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
		}
	}
}
点赞
  1. wzf说道:

    技术佬

  2. linkwater2022说道:

    api高手

  3. 贪财好色说道:

    怎么玩

回复 贪财好色 取消回复

电子邮件地址不会被公开。必填项已用 * 标注

×
订阅图标按钮