You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
star/tcping/cmd.go

175 lines
3.8 KiB
Go

2 years ago
package tcping
import (
"fmt"
"github.com/spf13/cobra"
"os"
"os/signal"
"strconv"
"syscall"
"time"
)
var (
counter int
timeout string
interval string
sigs chan os.Signal
httpMode bool
httpHead bool
httpPost bool
httpUA string
permanent bool
dnsServer []string
)
var Cmd = &cobra.Command{
Use: "tcping",
9 months ago
Short: "tcp/http ping 工具",
2 years ago
Long: "使用进行Tcp或Http协议进行ping探测",
Example: `
9 months ago
1. dns over tcp
2 years ago
> tcping google.com
9 months ago
2. dns over tcp with custom port
2 years ago
> tcping google.com 443
9 months ago
3. dns over http
2 years ago
> tcping -H google.com
9 months ago
4. dns with URI schema
2 years ago
> tcping http://hui.lu
`,
Run: func(cmd *cobra.Command, args []string) {
sigs = make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
if permanent && counter != 4 {
fmt.Println("不能同时指定-t与-c请检查您的输入")
return
}
if permanent {
counter = 0
}
if len(args) != 2 && len(args) != 1 {
cmd.Usage()
return
}
host := args[0]
var (
err error
port int
schema string
)
if len(args) == 2 {
port, err = strconv.Atoi(args[1])
if err != nil {
fmt.Println("端口应当为Int类型")
cmd.Usage()
return
}
schema = TCP.String()
} else {
var matched bool
schema, host, port, matched = CheckURI(host)
if !matched {
fmt.Println("不是一个合法的URI")
cmd.Usage()
return
}
}
var timeoutDuration time.Duration
if res, err := strconv.Atoi(timeout); err == nil {
timeoutDuration = time.Duration(res) * time.Millisecond
} else {
timeoutDuration, err = time.ParseDuration(timeout)
if err != nil {
fmt.Println("parse timeout failed", err)
cmd.Usage()
return
}
}
var intervalDuration time.Duration
if res, err := strconv.Atoi(interval); err == nil {
intervalDuration = time.Duration(res) * time.Millisecond
} else {
intervalDuration, err = time.ParseDuration(interval)
if err != nil {
fmt.Println("parse interval failed", err)
cmd.Usage()
return
}
}
var protocol Protocol
if httpMode {
protocol = HTTP
} else {
protocol, err = NewProtocol(schema)
if err != nil {
fmt.Println(err)
cmd.Usage()
return
}
}
if len(dnsServer) != 0 {
UseCustomeDNS(dnsServer)
}
parseHost := FormatIP(host)
target := Target{
Timeout: timeoutDuration,
Interval: intervalDuration,
Host: parseHost,
Port: port,
Counter: counter,
Protocol: protocol,
}
var pinger Pinger
switch protocol {
case TCP:
pinger = NewTCPing()
case HTTP, HTTPS:
var httpMethod string
switch {
case httpHead:
httpMethod = "HEAD"
case httpPost:
httpMethod = "POST"
default:
httpMethod = "GET"
}
pinger = NewHTTPing(httpMethod)
default:
fmt.Printf("schema: %s not support\n", schema)
cmd.Usage()
return
}
pinger.SetTarget(&target)
pingerDone := pinger.Start()
select {
case <-pingerDone:
break
case <-sigs:
break
}
fmt.Println(pinger.Result())
},
}
func init() {
Cmd.Flags().IntVarP(&counter, "counter", "c", 4, "ping的次数")
Cmd.Flags().BoolVarP(&permanent, "permanent", "t", false, "一直ping下去")
Cmd.Flags().StringVarP(&timeout, "timeout", "T", "1s", `超时时间, 单位为 "ns", "us" (or "µs"), "ms", "s", "m", "h"`)
Cmd.Flags().StringVarP(&interval, "interval", "I", "1s", `ping间隔时间, 单位为 "ns", "us" (or "µs"), "ms", "s", "m", "h"`)
Cmd.Flags().BoolVarP(&httpMode, "http", "H", false, `Use "HTTP" mode. will ignore URI Schema, force to http`)
Cmd.Flags().BoolVar(&httpHead, "head", false, `使用http head模式`)
Cmd.Flags().BoolVar(&httpPost, "post", false, `使用http post模式`)
Cmd.Flags().StringVar(&httpUA, "user-agent", "victorique/tcping", `自定义UA`)
Cmd.Flags().StringArrayVarP(&dnsServer, "dns-server", "D", nil, `使用自定义DNS服务器`)
}