为什么写了这个呢?

也是因为在工作中,团队中的成员需要压测tcp服务端,但是没有找到合适的压测工作,所以就用代码自己来实现一个简单的压测程序。

原本同时是想通过java或者php基于swoole的hyperf框架来实现,最终他是用了hyperf实现的,但是因为不好部署,所以我用go帮忙实现了以下。

这里其实也有问题的,自己随便写的一个小工具,功能什么的并不完善也不强大,不过你可以看看这个思路。

csv文件格式

login heartbeat
6822001800013201062961000201011076332E3031303030000037E7 680D02810003320106296100020100FBD7
6822001800013201062961000301011076332E303130303000006A72 680D02810003320106296100030100AA17
6822001800013201062961000401011076332E30313030300000FC58 680D028100033201062961000401001BD6

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package main

import (
	"encoding/csv"
	"encoding/hex"
	"flag"
	"fmt"
	"io"
	"net"
	"os"
	"time"
)

var ip string
var port int
var beat int
var delay int
var path string

func main() {

	flag.StringVar(&ip, "ip", "47.93.20.187", "服务端ip")
	flag.IntVar(&port, "port", 9001, "服务端port")
	flag.IntVar(&beat, "beat", 10, "心跳间隔单位秒")
	flag.IntVar(&delay, "delay", 100, "建立客户端延时单位毫秒")
	flag.StringVar(&path, "path", "test.csv", "csv文件路径")
	flag.Parse()

	file, err := os.Open(path)
	if err != nil {
		panic(err)
	}
	defer file.Close()
	reader := csv.NewReader(file)
	reader.FieldsPerRecord = -1

	var data [][]string
	for {
		csvdata, err := reader.Read() // 按行读取数据,可控制读取部分
		if err == io.EOF {
			break
		}
		data = append(data, csvdata)
	}
	ch := make(chan struct{}, 1)
	for k, line := range data {
		if k == 0 {
			continue
		}
		go tcp(k, line[0], line[1])
		if err != nil {
			panic(err)
		}
		time.Sleep(time.Duration(delay) * time.Millisecond)
	}
	<-ch
	return
}

func tcp(num int, signIn, heartbeat string) {
	p1, _ := hex.DecodeString(signIn)
	p2, _ := hex.DecodeString(heartbeat)
	conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", ip, port))
	if err != nil {
		panic(err)
	}
	fmt.Println("客户端" + fmt.Sprintf("%d", num) + "成功")
	fmt.Println("时间:"  + time.Now().Format(time.DateTime))
	if _, err := conn.Write(p1); err != nil {
		panic(err)
	}
	ticker := time.NewTicker(time.Second * time.Duration(beat)) // 创建一个定时器
	defer ticker.Stop()
	for range ticker.C {
		// 发送心跳消息
		_, err := conn.Write(p2)
		if err != nil {
			panic(err)
		}
		fmt.Println("发送心跳成功 时间:" + time.Now().Format(time.RFC3339))
	}
}