/
htlc.go
143 lines (132 loc) · 3.73 KB
/
htlc.go
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package main
import (
"crypto/tls"
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"runtime"
"time"
)
/****************************************
大量のHTTPSリクエストを生み出すコード
メソッドGet
宛先設定
プロセス数設定
無限ループ設定
楕円曲線暗号設定
body閲覧設定
[Example]
./htlc -i 127.0.0.1 -s
./htlc -i 127.0.0.1 -n 65000
./htlc -i 127.0.0.1 -n 500 -l
宛先サーバの性能によるが秒間2万リクエスト以上を記録
*****************************************/
func HttpsClient(ecdh bool) *http.Transport {
var tr = &http.Transport{ //デフォルト設定
TLSHandshakeTimeout: 1 * time.Second,
MaxIdleConnsPerHost: 65000,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
}
if ecdh { //楕円曲線暗号のみを使用する場合
tr = &http.Transport{
TLSHandshakeTimeout: 1 * time.Second,
MaxIdleConnsPerHost: 65000,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
CipherSuites: []uint16{
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
},
},
}
}
return tr
}
func connect(URL string, i int, loop, show, ecdh bool, result chan int) {
//tls設定作成
tr := HttpsClient(ecdh)
//クライアント作成
hc := &http.Client{Transport: tr}
for j := 0; j < 1 || loop; j++ { //デフォ1回、または無限ループする
req, _ := http.NewRequest("GET", URL, nil)
resp, err := hc.Do(req) //実際にリクエストを投げる
if err != nil {
//失敗した時
log.Println(err)
result <- 1
} else {
//成功した時
result <- 0
//待機時間をつくり同時アクティブセッション数を増やす
//time.Sleep(30000 * time.Millisecond)
body, _ := ioutil.ReadAll(resp.Body)
//io.Copy(ioutil.Discard, resp.Body)
defer resp.Body.Close()
if show { //フラグが有効な時だけ受信内容を表示
fmt.Printf("%s\n", resp.Header)
fmt.Printf("%s", body)
}
}
//使用していないコネクションを終了させる
tr.CloseIdleConnections()
}
}
func recieving(result chan int, loop bool, num int) {
//通信結果を受け取るためのプロセス
success := 0
failed := 0
all := 0.0
s := time.Now()
for loop { //無限ループする場合
r := <-result
all = all + 1
if r == 0 {
success = success + 1
}
if int(all)%10000 == 0 { //結果を1万回ごとに表示
fmt.Println("all:", all, "Suc:", success, "q/s:", 10000/time.Now().Sub(s).Seconds())
s = time.Now()
}
}
for i := 0; i < num; i++ { //指定プロセス数だけの時
r := <-result
if r == 0 {
success = success + 1
} else {
failed = failed + 1
}
}
fmt.Println("RESULT Success : ", success, " Failed : ", failed)
}
func main() {
fmt.Println("Please wait....")
URL := flag.String("i", "https://127.0.0.1/", "dst server URL")
num := flag.Int("n", 1, "process num")
loop := flag.Bool("l", false, "loop flag")
ecdh := flag.Bool("e", false, "ecdh flag")
show := flag.Bool("s", false, "show body flag")
flag.Parse()
result := make(chan int)
//通信結果を受け取るためのプロセス
go recieving(result, *loop, *num)
t := time.Now()
for i := 0; i < *num; i++ { //通信プロセスの作成
go connect(*URL, i, *loop, *show, *ecdh, result)
}
f := time.Now()
//通信プロセスの作成時間
fmt.Println("Create process time: ", f.Sub(t))
//現在動いてるプロセス数
fmt.Println("Current Process num: ", runtime.NumGoroutine())
//mainプロセスを待機させておく
time.Sleep(3 * time.Second) //プロセス作成時間分待機
//プロセスが残ってるうちは待機
for runtime.NumGoroutine() > 4 || *loop {
time.Sleep(1 * time.Second)
}
//終了時のプロセス数
fmt.Println("Current Process num: ", runtime.NumGoroutine())
}