Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: princepereira/TcpClientServer
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.0.1
Choose a base ref
...
head repository: princepereira/TcpClientServer
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
  • 2 commits
  • 5 files changed
  • 2 contributors

Commits on Oct 14, 2024

  1. Saving result to file.

    princepereira committed Oct 14, 2024
    Copy the full SHA
    190b926 View commit details

Commits on Oct 16, 2024

  1. Merge pull request #3 from princepereira/ppereira-saveoutput

    Saving result to file.
    princepereira committed Oct 16, 2024
    Copy the full SHA
    38ed634 View commit details
Showing with 92 additions and 15 deletions.
  1. BIN bins/client.exe
  2. +5 −0 bins/result.json
  3. BIN bins/server.exe
  4. +14 −1 client/main.go
  5. +73 −14 util/util.go
Binary file modified bins/client.exe
Binary file not shown.
5 changes: 5 additions & 0 deletions bins/result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"total_connections": 2,
"failed_connections": 2,
"iteration": 1
}
Binary file modified bins/server.exe
Binary file not shown.
15 changes: 14 additions & 1 deletion client/main.go
Original file line number Diff line number Diff line change
@@ -23,6 +23,8 @@ var failedCons *failedConnsStruct // Stores failed info for each iterati
var serverInfoMap *sync.Map
var disableKeepAlive bool
var keepAliveTimeOut int
var resultFilePath string // If the flag is not empty, then it stores the path to result file.
var testcaseName string // If the flag is not empty, then it stores the name of the test.

type failedConnsStruct struct {
failedCons []util.ConnInfo
@@ -86,6 +88,13 @@ func main() {
iter, _ := strconv.Atoi(args[util.AtribIterations])
util.SetMaxDropThreshold(args[util.AtribMaxDropThreshold])
enableMetrics, _ := strconv.ParseBool(args[util.AtribEnableMetrics])
resultFilePath = args[util.AtribOutFile]
testcaseName = args[util.AtribTestName]

if resultFilePath != util.ConstEmpty {
// remove the file if it exists
util.RemoveResultFile(resultFilePath)
}

wg := new(sync.WaitGroup)

@@ -136,7 +145,11 @@ func main() {

failedConnCount := failedCons.size()
passedConnCount := conns - failedConnCount
fmt.Printf("\n\n\n#======= ConnectionsSucceded:%d, ConnectionsFailed:%d , Iteration:%d \n", passedConnCount, failedConnCount, turn)
fmt.Printf("\n\n\n#======= ConnectionsSucceded:%d, ConnectionsFailed:%d , Iteration:%d , resultFilePath : %v \n", passedConnCount, failedConnCount, turn, resultFilePath)

if resultFilePath != util.ConstEmpty {
util.SaveResultToFile(conns, passedConnCount, failedConnCount, turn, testcaseName, resultFilePath)
}

if enableMetrics {
util.UpdateMetricResult(metric, startTS, passedConnCount, failedConnCount)
87 changes: 73 additions & 14 deletions util/util.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package util

import (
"encoding/json"
"fmt"
"log"
"net"
@@ -11,7 +12,7 @@ import (
)

const (
Version = "v19.06.2024"
Version = "v16.10.2024"
MaxDropPackets = 100
HttpPort = 8090
HttpPrometheusPort = 8090
@@ -46,6 +47,8 @@ const (
AtribMaxDropThreshold = "-mdt"
AtribServerInfo = "ServerInfo"
AtribVersion = "-v"
AtribOutFile = "-file"
AtribTestName = "-name"
)

var argKeys = map[string]bool{
@@ -66,6 +69,8 @@ var argKeys = map[string]bool{
AtribTimeoutApplicationWait: true,
AtribVersion: true,
AtribMaxDropThreshold: true,
AtribOutFile: true,
AtribTestName: true,
}

var (
@@ -78,6 +83,7 @@ var (
)

const (
ConstEmpty = ""
ConstFalse = "false"
ConstTrue = "true"
ConstTCP = "tcp"
@@ -113,6 +119,14 @@ type ConnectionMetrics struct {
UDP Metrics `json:"udp,omitempty"`
}

type ConnectionResult struct {
TestcaseName string `json:"testcase_name"`
TotalConnections int `json:"total_connections"`
FailedConnections int `json:"failed_connections"`
SuccessfulConnections int `json:"successful_connections"`
Iteration int `json:"iteration"`
}

func PrintServerBanner(config map[string]string) {
log.Println(" ")
log.Println("#===========================================#")
@@ -163,6 +177,12 @@ func PrintClientBanner(config map[string]string) {
log.Printf("# TimeoutKeepAlive : %s \n", config[AtribTimeoutKeepAlive])
}
log.Printf("# MetricsEnabled : %s \n", config[AtribEnableMetrics])
if config[AtribOutFile] != ConstEmpty {
log.Printf("# ResultFile : %s \n", config[AtribOutFile])
}
if config[AtribTestName] != ConstEmpty {
log.Printf("# TestcaseName : %s \n", config[AtribTestName])
}
log.Println("#===========================================#")
log.Println(" ")
}
@@ -192,6 +212,8 @@ func ValidateArgs() (map[string]string, error) {
args[AtribTimeoutApplicationWait] = DefaultTimeoutApplicationWait
args[AtribIterations] = DefaultIterations
args[AtribMaxDropThreshold] = strconv.Itoa(MaxDropThreshold)
args[AtribOutFile] = ConstEmpty
args[AtribTestName] = ConstEmpty

for i := 1; i < len(os.Args); i++ {

@@ -294,19 +316,21 @@ func ClientHelp() {
str = str + "Format : .\\client.exe -i <IP> -p <Port> -c <Number of Connections> -r <Number of Requests/Connection> -d <Delay (in ms) between each request> \n"
str = str + "\nEg : .\\client.exe -i 127.0.0.1 -p 4444 -c 1 -r 10000 -d 1 \n"
str = str + "\nParameters (Optional, Mandatory*): \n\n"
str = str + " -i : (*) IPv4/IPv6 Address of the server \n"
str = str + " -p : (*) Port number of the server \n"
str = str + " -c : (*) Number of clients/threads/connections \n"
str = str + " -r : (*) Number of requests per connection \n"
str = str + " -d : (*) Delay/Sleep/Time between each request for a single connection (in milliseconds) \n"
str = str + " -sp : Source port to be chosen for client connections. Mandatory to provide Source Ip (-si) as well if this option is specified \n"
str = str + " -si : Source IP to be chosen for client connections. Only valid if Source Port is specified \n"
str = str + " -it : Number of iterations. Default: 1 \n"
str = str + " -pr : Proto used. Options: TCP/UDP. Default: TCP \n"
str = str + " -mdt : MaxDropThreshold. Max time wait before consecutive drops \n"
str = str + " -dka : Disable KeepAlive. Options: True/False. Default: False \n"
str = str + " -tka : KeepAlive Time in milliseconds. Default: 15 seconds \n"
str = str + " -em : Enable prometheus metrics. Default: False \n"
str = str + " -i : (*) IPv4/IPv6 Address of the server \n"
str = str + " -p : (*) Port number of the server \n"
str = str + " -c : (*) Number of clients/threads/connections \n"
str = str + " -r : (*) Number of requests per connection \n"
str = str + " -d : (*) Delay/Sleep/Time between each request for a single connection (in milliseconds) \n"
str = str + " -sp : Source port to be chosen for client connections. Mandatory to provide Source Ip (-si) as well if this option is specified \n"
str = str + " -si : Source IP to be chosen for client connections. Only valid if Source Port is specified \n"
str = str + " -it : Number of iterations. Default: 1 \n"
str = str + " -pr : Proto used. Options: TCP/UDP. Default: TCP \n"
str = str + " -mdt : MaxDropThreshold. Max time wait before consecutive drops \n"
str = str + " -dka : Disable KeepAlive. Options: True/False. Default: False \n"
str = str + " -tka : KeepAlive Time in milliseconds. Default: 15 seconds \n"
str = str + " -em : Enable prometheus metrics. Default: False \n"
str = str + " -file : Set the file name to store the result \n"
str = str + " -name : Set the name of the testcase \n"
str = str + "\n#==============================#\n"
log.Println(str)
}
@@ -366,3 +390,38 @@ func IsConnClosed(errMsg string) bool {
}
return false
}

// SaveResultToFile : Save the result to a file
func SaveResultToFile(total, succeeded, failed, iteration int, testcaseName, resultFilePath string) {
log.Printf("Saving the result of test %s to the file : %s\n", testcaseName, resultFilePath)
// Save the result to a file
connresult := ConnectionResult{
TestcaseName: testcaseName,
TotalConnections: total,
SuccessfulConnections: succeeded,
FailedConnections: failed,
Iteration: iteration,
}
jsonData, err := json.MarshalIndent(connresult, "", " ")
if err != nil {
log.Println("Error in marshalling the result : ", err)
return
}
err = os.WriteFile(resultFilePath, jsonData, 0644)
if err != nil {
log.Println("Error in saving the result : ", err)
return
}
log.Printf("Result of test %s saved successfully to the file : %s\n", testcaseName, resultFilePath)
}

func RemoveResultFile(resultFilePath string) {
_, err := os.Stat(resultFilePath)
if os.IsNotExist(err) {
return
}
err = os.Remove(resultFilePath)
if err != nil {
log.Println("Error in removing the file : ", err)
}
}