TCP Line Protocol Server with Deadlines and Graceful Shutdown
Concurrent TCP server implementing a simple line-based protocol with deadlines and graceful shutdown.
main.go
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
package main
import (
"bufio"
"bytes"
"context"
"fmt"
"log"
"net"
"strings"
"time"
)
const newline byte = 10
func handleConn(ctx context.Context, c net.Conn) {
_ = ctx
defer c.Close()
r := bufio.NewReaderSize(c, 64*1024)
for {
if err := c.SetReadDeadline(time.Now().Add(30 * time.Second)); err != nil {
return
}
line, err := r.ReadBytes(newline)
if err != nil {
return
}
msg := strings.TrimSpace(string(bytes.TrimSpace(line)))
if strings.EqualFold(msg, "quit") {
return
}
if err := c.SetWriteDeadline(time.Now().Add(10 * time.Second)); err != nil {
return
}
fmt.Fprintf(c, "OK %d bytes%c", len(msg), newline)
}
}
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ln, err := net.Listen("tcp", "127.0.0.1:9090")
if err != nil {
log.Fatalf("listen: %v", err)
}
defer ln.Close()
go func() {
<-ctx.Done()
ln.Close()
}()
log.Printf("tcp server listening on %s", ln.Addr().String())
for {
c, err := ln.Accept()
if err != nil {
return
}
go handleConn(ctx, c)
}
}How It Works
Concurrent TCP server implementing a simple line-based protocol with deadlines and graceful shutdown.
Listens on a TCP port, spawns goroutines per client, sets read and write deadlines, reads newline-delimited commands, responds accordingly, and shuts down via context cancellation to close listeners and wait for workers.
Key Concepts
- 1Deadlines prevent stuck connections from hanging the server.
- 2WaitGroup and context ensure orderly shutdown.
- 3Line-based protocol makes parsing simple and predictable.
When to Use This Pattern
- Prototype for custom text protocols such as chat or command shells.
- Integration test server for network clients.
- Educational example of concurrent TCP handling.
Best Practices
- Sanitize and limit input to prevent abuse.
- Handle partial reads, writes, and EOF explicitly.
- Close client connections in defer blocks to avoid leaks.
Go Version1.18+
Difficultyintermediate
Production ReadyYes
Lines of Code65