为什么写了这个呢?

也是因为在工作中,团队中的成员需要压测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
83
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))
}
}