I am trying to achieve a server listening on multiple sockets. The first approach that come to mind is creating a goroutine for each port and blocking the main go routine with a channel or wait group. This appears to work at first but opening more than one TCP connection to each client suddenly breaks everything and freezes up my PC.
I’d love to hear you would go about achieving something this and I’d also appreciate any pointers to resources to look at.
Edit: I included a minimal reproduction
package main
import (
"fmt"
"tcp"
)
func main() {
for i := 0; i < 4; i++ {
address := fmt.Sprintf("500%v", i)
go startServer(address)
}
}
func startServer(address string){
listener, err := net.ListenTCP(network, laddr)
if err != nil {
return
}
for {
conn, err := listener.Accept()
//do something with connection
}
}
ch1 := make(chan []byte)
go socketHandler(ch1, addr1)
ch2 := make(chan []byte)
go socketHandler(ch2, addr2)
for {
select {
case req1 := <- ch1:
handleRequest(req1)
case req2 := <- ch2:
handleRequest(req2)
}
}
...
func socketHandler(ch chan []byte, addr AddrType) {
// listen and accept omitted
b := make([]byte, bufferLen)
for {
conn.Read(b)
ch <- b
}
}
There’s lots of error handling missing, and close handling, etc. You could add another channel for each socket to return results to socketHandler, etc.
Possibly this doesn’t solve your lockups, but it puts all the request handling logic on the main goroutine (which could be bad or good) where it might not cause race conditions if your separate server goroutines had accessed shared state.
@Paul_Arah I think what you started with should actually work fine - you just need to handle each new connection in its own go routine. You only have a single go routine running for each “server port” but you’re trying to connect multiple clients to each of those ports. From inside each server go routine, create a new go routine to handle each incoming connection.
In other words, if you have 2 ports open, you’d have 2 long lived go routines, then if 2 clients connected to each port (4 total clients) then you’d have 6 total go routines, 4 of which are ephemeral and live as long as the connection is alive.