Hi!
I recently wrote some code to load test a proxy by sending lots of tcp packets.
At first I wrote it in a for loop but wanted to learn more about concurrancy and added go routines.
I noticed that when I added many requests the code would fail:
signal SIGSEGV: segmentation violation code=0x1 “Fprintf”
and
runtime error: invalid memory address or nil pointer dereference
The error from net.dial is:
connect: cannot assign requested address
It looks kind of like there might not be anymore available sockets once the goroutines eclipse ~30,000.
Here’s the code:
package main
import (
"bufio"
"fmt"
"log"
"net"
"os"
"time"
)
func main() {
start := time.Now()
userendpoint := userEndpoint()
userport := userPort()
userpoints := userPoints()
var name string
var port string
var points int
name = *userendpoint
port = *userport
points = *userpoints
c := make(chan string)
fmt.Printf("You selected %s over %s and will send %d times\n", name, port, points)
for k := 0; k < points; k++ {
go sendPoints(name, port, points, c)
}
for i := 0; i < points; i++ {
fmt.Println(<-c)
fmt.Printf("This is the %v pass", i)
}
fmt.Println("took:", time.Since(start))
}
func sendPoints(name, port string, points int, c chan string) {
// connect to this socket
conn, err := net.Dial("tcp", name+":"+port)
if err != nil {
log.Fatal(err)
}
for i := 0; i < points; i++ {
reader := "prod.monitoring.test 1 source=mysource"
fmt.Fprintf(conn, reader+"\n")
//fmt.Printf("This is the %v pass\n", i)
c <- ""
//time.Sleep(100 * time.Millisecond)
}
}
func userEndpoint() *string {
fmt.Println("What is the IP or DNS name you wish to send points to?")
var name string
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
name = scanner.Text()
if name == "" {
name = "server.server.com"
}
if err := scanner.Err(); err != nil {
fmt.Println("Error reading from input: ", err)
}
return &name
}
func userPort() *string {
fmt.Println("What is the port you wish to send points to?")
var port string
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
port = scanner.Text()
if port == "" {
port = "2878"
}
if err := scanner.Err(); err != nil {
fmt.Println("Error reading from input: ", err)
}
return &port
}
func userPoints() *int {
fmt.Println("How many times do you wish to send?")
var i int
scanner := bufio.NewReader(os.Stdin)
for {
_, err := fmt.Fscan(scanner, &i)
if err == nil && i >= 0 {
break
}
}
return &i
}
Thoughts?
Thanks in advance!