Reputation: 895
coders. Here is the basic tcp-server, that accepts connection, reads the incoming data and writes back.
package main
import (
"bufio"
"io"
"log"
"net"
)
func main() {
li, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatalln(err)
}
defer li.Close()
for {
conn, err := li.Accept()
if err != nil {
log.Fatalln(err)
}
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
ln := scanner.Text()
io.WriteString(conn, ln+"\n")
}
conn.Close()
}
}
However, there is a nested loop for scanner and declaring new scanner on each iteration of external loop. I heard, that nested loops lead to extra complexety and maybe declaring new scanner on each iteration of infinite loop leads to some memory leaks. Actually, I don't know how to do it in another way and I'm just want to ask 2 things:
Is it possible to do the same in another way?
Do we actually need more optimization on such low-level server
abstraction?
Upvotes: 1
Views: 230
Reputation: 34312
The outer loop is waiting for new connections, the inner loop is parsing the input data, so from that point of view it's fine. Not all nested loops are evil. However, while you're handling that single connection, the server is not accepting them any more (you can test that by trying to connect to the server from multiple clients). To fix that, handle the connection in a goroutine:
for {
conn, err := li.Accept()
if err != nil {
log.Fatalln(err)
}
go func() {
defer conn.Close()
scanner := bufio.NewScanner(conn)
for scanner.Scan() {
ln := scanner.Text()
io.WriteString(conn, ln+"\n")
}
}()
}
Upvotes: 3