net

package module
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 26, 2026 License: MIT Imports: 10 Imported by: 0

README ΒΆ

TCP Network Library for Go

A high-performance, Linux-native TCP networking library built directly on syscalls for educational purposes and deep understanding of network programming fundamentals.

Go Version License Platform


🎯 Project Overview

This library implements a production-ready TCP server using raw Linux syscalls, demonstrating how modern network servers work under the hood. It's designed as both a learning resource and a functional foundation for building custom network protocols.

Why This Exists

Most developers use high-level networking libraries without understanding how they work. This project teaches you:

  • How TCP networking works at the syscall level
  • Why epoll is critical for high-performance servers
  • How to tune TCP options for different workloads
  • Production patterns for connection management and graceful shutdown
Who Is This For?
  • Students learning network programming
  • Engineers wanting to understand networking internals
  • Interviewers preparing for system design questions
  • Developers building custom protocols or high-performance servers

✨ Features

Core Capabilities
  • βœ… Epoll-based event loop - Scalable to 10,000+ concurrent connections
  • βœ… Production-grade error handling - EINTR, EAGAIN, EMFILE, etc.
  • βœ… Graceful shutdown - Drain connections before exit
  • βœ… Connection tracking - Real-time metrics and limits
  • βœ… Context support - Modern Go cancellation patterns
  • βœ… Comprehensive testing - Full test suite included
  • βœ… Advanced TCP options - TCP_DEFER_ACCEPT, TCP_FASTOPEN, SO_REUSEPORT
What Makes It Production-Ready?
Feature Status Why It Matters
Epoll event loop βœ… O(1) scaling vs O(n) for select/poll
Connection limits βœ… Prevent resource exhaustion
Graceful shutdown βœ… Don't kill active requests
Thread-safe βœ… Safe concurrent access
Observable βœ… Metrics for monitoring
IPv6 dual-stack βœ… Handle both IPv4 and IPv6
Comprehensive tests βœ… Confidence in production

πŸš€ Quick Start

Prerequisites
  • Go 1.21 or later
  • Linux kernel 2.6+ (for epoll support)
Installation
# Clone or download the library
git clone https://github.com/yourusername/net.git
cd net

# Initialize Go module
go mod tidy

# Build examples
go build -o bin/echo-server ./cmd/echo-server
go build -o bin/http-server ./cmd/http-server
go build -o bin/benchmark ./cmd/benchmark
Run Echo Server
# Terminal 1: Start server
./bin/echo-server -port 8080

# Terminal 2: Test it
echo "Hello, World!" | nc localhost 8080
# Output: Hello, World!
Run HTTP Server
# Start HTTP server
./bin/http-server -port 8081

# Visit in browser
open http://localhost:8081

# Or use curl
curl http://localhost:8081/hello
# Output: Hello, World!
Benchmark Performance
# Terminal 1: Start echo server
./bin/echo-server -port 8080

# Terminal 2: Run benchmark
./bin/benchmark -port 8080 -connections 100 -duration 10

# Expected output:
# Requests/sec: 80,000+
# Throughput: 160+ MB/s
# Average Latency: <2ms

πŸ“– Usage Examples

Basic Echo Server
package main

import (
    "io"
    net "github.com/yourusername/net"
)

func main() {
    // Create configuration
    cfg := net.DefaultConfig().
        WithPort(8080).
        WithMaxConns(10000)
    
    // Create listener
    listener, err := net.Listen(cfg)
    if err != nil {
        panic(err)
    }
    defer listener.Close()
    
    // Accept connections
    for {
        conn, err := listener.Accept()
        if err != nil {
            continue
        }
        
        // Handle in goroutine
        go func(c net.Conn) {
            defer c.Close()
            io.Copy(c, c) // Echo back
        }(conn)
    }
}
HTTP/1.1 Server
package main

import (
    "bufio"
    "fmt"
    "time"
    net "github.com/yourusername/net"
)

func main() {
    cfg := net.DefaultConfig().
        WithPort(8080).
        WithDeferAccept(1 * time.Second) // Optimize for HTTP
    
    listener, _ := net.Listen(cfg)
    
    handler := func(conn net.Conn) {
        defer conn.Close()
        reader := bufio.NewReader(conn)
        
        // Read request
        requestLine, _ := reader.ReadString('\n')
        
        // Send response
        response := "HTTP/1.1 200 OK\r\n"
        response += "Content-Type: text/plain\r\n"
        response += "Content-Length: 13\r\n"
        response += "\r\n"
        response += "Hello, World!"
        
        conn.Write([]byte(response))
    }
    
    server := net.NewServer(listener, handler, 0)
    server.Serve()
}
With Graceful Shutdown
package main

import (
    "os"
    "os/signal"
    "syscall"
    "time"
    net "github.com/yourusername/net"
)

func main() {
    cfg := net.DefaultConfig().WithPort(8080)
    listener, _ := net.Listen(cfg)
    
    // Setup signal handling
    sigChan := make(chan os.Signal, 1)
    signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
    
    // Start server
    server := net.NewServer(listener, handleConnection, 0)
    go server.Serve()
    
    // Wait for shutdown signal
    <-sigChan
    
    // Graceful shutdown with 30s timeout
    server.Shutdown(30 * time.Second)
}

func handleConnection(conn net.Conn) {
    defer conn.Close()
    // Your handler logic
}

πŸ”§ Configuration Options

Basic Configuration
cfg := net.DefaultConfig()
cfg.Port = 8080                    // Listen port
cfg.MaxConns = 10000               // Max concurrent connections (0 = unlimited)
cfg.Backlog = 4096                 // SYN queue size
Socket Options
cfg.ReuseAddr = true               // SO_REUSEADDR - allow quick restart
cfg.ReusePort = false              // SO_REUSEPORT - multi-process load balancing
cfg.NoDelay = true                 // TCP_NODELAY - disable Nagle's algorithm
cfg.KeepAlive = true               // SO_KEEPALIVE - detect dead connections
cfg.QuickAck = true                // TCP_QUICKACK - disable delayed ACKs
Advanced TCP Options
cfg.DeferAccept = 1 * time.Second  // TCP_DEFER_ACCEPT - wait for data
cfg.FastOpen = true                // TCP_FASTOPEN - lower latency
cfg.SendBuffer = 256 * 1024        // SO_SNDBUF - send buffer size
cfg.RecvBuffer = 256 * 1024        // SO_RCVBUF - receive buffer size
Builder Pattern
cfg := net.DefaultConfig().
    WithPort(8080).
    WithMaxConns(10000).
    WithReusePort(true).
    WithLogger(logger)

πŸ“Š Performance

Benchmarks

Tested on: Intel i7-9750H, 16GB RAM, Ubuntu 22.04

Metric Result Workload
Requests/sec 85,000+ 100 connections, 1KB messages
Throughput 166 MB/s Echo server, 1KB messages
Latency (p50) 1.2ms 100 concurrent connections
Latency (p99) 3.5ms 100 concurrent connections
Max connections 10,000+ Limited by file descriptors
Optimization Tips

For Low Latency (RPC, Games):

cfg.NoDelay = true        // Disable Nagle
cfg.QuickAck = true       // Disable delayed ACKs

For High Throughput (File Transfer):

cfg.NoDelay = false       // Enable Nagle
cfg.SendBuffer = 1024 * 1024
cfg.RecvBuffer = 1024 * 1024

For HTTP Servers:

cfg.DeferAccept = 1 * time.Second  // Don't wake up until data arrives
cfg.NoDelay = true                  // Low latency for requests

πŸ—οΈ Architecture

Component Overview
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         Application Layer                β”‚
β”‚    (HTTP, Redis, Custom Protocol)        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚
                    β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          Server (server.go)              β”‚
β”‚  β€’ Accept connections via epoll          β”‚
β”‚  β€’ Connection limit enforcement          β”‚
β”‚  β€’ Graceful shutdown coordination        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β–Ό                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Listener         β”‚  β”‚ Connection       β”‚
β”‚ (listener.go)    β”‚  β”‚ (conn.go)        β”‚
β”‚ β€’ Epoll loop     β”‚  β”‚ β€’ Read/Write     β”‚
β”‚ β€’ Accept queue   β”‚  β”‚ β€’ Deadlines      β”‚
β”‚ β€’ Stats tracking β”‚  β”‚ β€’ Half-close     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚                   β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚       Linux Kernel (syscalls)            β”‚
β”‚  socket β€’ bind β€’ listen β€’ epoll_wait    β”‚
β”‚  accept β€’ read β€’ write β€’ close          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“š What Can You Build?

This library is a foundation for building:

βœ… Ready to Build Now
  • HTTP/1.1 servers - Web servers, REST APIs, proxies
  • WebSocket servers - Chat, games, real-time dashboards
  • Redis clone - Cache server, message queue, pub/sub
  • Custom databases - KV stores, time-series, graph DBs
  • RPC frameworks - JSON-RPC, custom protocols
  • Game servers - Multiplayer, turn-based, MMO
  • Load balancers - TCP/HTTP reverse proxies
  • Message queues - NATS-like pub/sub, work queues
⚠️ Requires Additional Work
  • HTTP/2 - Needs TLS wrapper + binary framing
  • gRPC - Requires HTTP/2 + Protobuf
  • TLS/HTTPS - Wrap with crypto/tls

See WHAT_TO_BUILD.md for detailed project ideas.


πŸ§ͺ Testing

Run All Tests
# Run test suite
go test -v

# With race detector
go test -v -race

# With coverage
go test -v -cover
Test Coverage
  • βœ… Graceful shutdown
  • βœ… Concurrent connections (50+)
  • βœ… Read/write timeouts
  • βœ… Connection limits
  • βœ… Large payloads (100KB+)

See TESTING.md for the complete testing guide.


πŸ“– Documentation


πŸŽ“ Learning Path

New to network programming? Follow this path:

  1. Week 1: Read LEARNING_GUIDE.md - Build a simple server
  2. Week 2: Complete the epoll exercises
  3. Week 3: Build an HTTP/1.1 server
  4. Month 2: Build a Redis clone
  5. Month 3: Build a load balancer
  6. Beyond: Build something you'll actually use!

Remember: Don't just copy the code. Rebuild it yourself to truly understand!


πŸ› Known Limitations

  • Linux only - Uses Linux-specific epoll API
  • No TLS - Requires wrapping with crypto/tls
  • TCP only - No UDP support
  • No HTTP parser - You build the protocol layer

🀝 Contributing

Contributions are welcome! Areas for improvement:

  • Add UDP support
  • Port to macOS (kqueue) and Windows (IOCP)
  • Built-in TLS support
  • More example protocols (MQTT, STOMP, etc.)

πŸ“ License

This project is licensed under the MIT License - see the LICENSE file for details.


πŸ™ Acknowledgments

  • W. Richard Stevens - For the networking bible
  • Dan Kegel - For documenting the C10K problem
  • Linux kernel team - For epoll
  • Go team - For goroutines and channels

Built with ❀️ for learning and understanding network programming

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

This section is empty.

Variables ΒΆ

View Source
var (
	ErrConnClosed = errors.New("connection closed")
	ErrTimeout    = errors.New("i/o timeout")
)
View Source
var (
	ErrListenerClosed  = errors.New("listener closed")
	ErrMaxConnsReached = errors.New("max connections reached")
	ErrInvalidConfig   = errors.New("invalid configuration")
	ErrAcceptTimeout   = errors.New("accept timeout")
)
View Source
var (
	ErrServerClosed = errors.New("server closed")
)

Functions ΒΆ

func FD_ISSET ΒΆ added in v0.0.2

func FD_ISSET(fd int, set *syscall.FdSet) bool

FD_ISSET checks if a bit is set in the FdSet

func FD_SET ΒΆ added in v0.0.2

func FD_SET(fd int, set *syscall.FdSet)

FD_SET sets a bit in the FdSet

func FD_ZERO ΒΆ added in v0.0.2

func FD_ZERO(set *syscall.FdSet)

FD_ZERO clears an FdSet

Types ΒΆ

type Config ΒΆ

type Config struct {
	Network string // Only "tcp" supported for now
	Port    int    // Port to listen on

	// Socket options
	ReuseAddr bool // SO_REUSEADDR - allow binding to TIME_WAIT addresses
	ReusePort bool // SO_REUSEPORT - allow multiple processes on same port
	NoDelay   bool // TCP_NODELAY - disable Nagle's algorithm
	KeepAlive bool // SO_KEEPALIVE - enable TCP keepalive
	QuickAck  bool // TCP_QUICKACK - disable delayed ACKs

	// Advanced TCP options
	DeferAccept time.Duration // TCP_DEFER_ACCEPT - wait for data before accept
	FastOpen    bool          // TCP_FASTOPEN - enable TFO for lower latency

	// Buffer sizes (0 = use system defaults)
	SendBuffer int // SO_SNDBUF - send buffer size
	RecvBuffer int // SO_RCVBUF - receive buffer size

	// Connection limits
	Backlog  int // Listen backlog (SYN queue size)
	MaxConns int // Maximum concurrent connections (0 = unlimited)

	// Timeouts
	AcceptTimeout time.Duration // Timeout for accept operations

	// Observability
	Logger Logger // Optional structured logger
}

Config holds listener configuration

func DefaultConfig ΒΆ

func DefaultConfig() *Config

DefaultConfig returns a production-ready default configuration

func (*Config) Validate ΒΆ added in v0.0.2

func (c *Config) Validate() error

Validate checks if the configuration is valid

func (*Config) WithBacklog ΒΆ added in v0.0.2

func (c *Config) WithBacklog(backlog int) *Config

WithBacklog sets the listen backlog

func (*Config) WithBufferSizes ΒΆ added in v0.0.2

func (c *Config) WithBufferSizes(send, recv int) *Config

WithBufferSizes sets send and receive buffer sizes

func (*Config) WithDeferAccept ΒΆ added in v0.0.2

func (c *Config) WithDeferAccept(duration time.Duration) *Config

WithDeferAccept sets TCP_DEFER_ACCEPT timeout

func (*Config) WithLogger ΒΆ added in v0.0.2

func (c *Config) WithLogger(logger Logger) *Config

WithLogger sets the logger

func (*Config) WithMaxConns ΒΆ added in v0.0.2

func (c *Config) WithMaxConns(maxConns int) *Config

func (*Config) WithPort ΒΆ added in v0.0.2

func (c *Config) WithPort(port int) *Config

func (*Config) WithReusePort ΒΆ added in v0.0.2

func (c *Config) WithReusePort(reusePort bool) *Config

type Conn ΒΆ

type Conn interface {
	io.ReadWriteCloser

	// LocalAddr returns the local network address
	LocalAddr() string

	// RemoteAddr returns the remote network address
	RemoteAddr() string

	// SetDeadline sets read and write deadlines
	SetDeadline(t time.Time) error

	// SetReadDeadline sets the read deadline
	SetReadDeadline(t time.Time) error

	// SetWriteDeadline sets the write deadline
	SetWriteDeadline(t time.Time) error

	// CloseRead closes the read side of the connection
	CloseRead() error

	// CloseWrite closes the write side of the connection
	CloseWrite() error
}

Conn represents a network connection

func Dial ΒΆ

func Dial(network, host string, port int) (Conn, error)

Dial connects to the address on the named network

func DialTimeout ΒΆ added in v0.0.2

func DialTimeout(network, host string, port int, timeout time.Duration) (Conn, error)

DialTimeout connects with a timeout

type Listener ΒΆ

type Listener interface {
	Accept() (Conn, error)
	AcceptContext(ctx context.Context) (Conn, error)
	Close() error
	GracefulShutdown(timeout time.Duration) error
	Addr() string
	Stats() ListenerStats
}

Listener defines the interface for accepting connections

func Listen ΒΆ

func Listen(cfg *Config) (Listener, error)

Listen creates a new production-grade listener

type ListenerStats ΒΆ added in v0.0.2

type ListenerStats struct {
	ActiveConns   int64
	TotalAccepted int64
	TotalRejected int64
	TotalErrors   int64
}

ListenerStats provides runtime statistics

type LogLevel ΒΆ added in v0.0.2

type LogLevel int
const (
	DebugLevel LogLevel = iota
	InfoLevel
	ErrorLevel
)

type Logger ΒΆ added in v0.0.2

type Logger interface {
	Debug(msg string, fields ...any)
	Info(msg string, fields ...any)
	Error(msg string, fields ...any)
}

Logger interface for structured logging

type Server ΒΆ

type Server struct {
	// contains filtered or unexported fields
}

Server wraps a listener and handles connections with a handler function

func NewServer ΒΆ

func NewServer(listener Listener, handler func(Conn), maxConnections int) *Server

NewServer creates a new server with the given listener and handler

func (*Server) Close ΒΆ added in v0.0.2

func (s *Server) Close() error

Close immediately closes the server

func (*Server) Ready ΒΆ added in v0.0.2

func (s *Server) Ready() <-chan struct{}

Ready returns a channel that is closed when the server is ready to accept connections

func (*Server) Serve ΒΆ

func (s *Server) Serve() error

Serve starts accepting connections and handling them

func (*Server) Shutdown ΒΆ

func (s *Server) Shutdown(timeout time.Duration) error

Shutdown gracefully shuts down the server

func (*Server) Stats ΒΆ added in v0.0.2

func (s *Server) Stats() struct {
	ActiveConnections int64
	ListenerStats     ListenerStats
}

Stats returns server statistics

type SimpleLogger ΒΆ added in v0.0.2

type SimpleLogger struct {
	// contains filtered or unexported fields
}

SimpleLogger is a basic implementation of the Logger interface

func NewSimpleLogger ΒΆ added in v0.0.2

func NewSimpleLogger(level LogLevel) *SimpleLogger

NewSimpleLogger creates a new simple logger

func (*SimpleLogger) Debug ΒΆ added in v0.0.2

func (l *SimpleLogger) Debug(msg string, fields ...any)

func (*SimpleLogger) Error ΒΆ added in v0.0.2

func (l *SimpleLogger) Error(msg string, fields ...any)

func (*SimpleLogger) Info ΒΆ added in v0.0.2

func (l *SimpleLogger) Info(msg string, fields ...any)

type TimeoutError ΒΆ

type TimeoutError struct {
	// contains filtered or unexported fields
}

TimeoutError represents a timeout error

func (*TimeoutError) Error ΒΆ

func (e *TimeoutError) Error() string

func (*TimeoutError) Temporary ΒΆ

func (e *TimeoutError) Temporary() bool

func (*TimeoutError) Timeout ΒΆ

func (e *TimeoutError) Timeout() bool

Directories ΒΆ

Path Synopsis
cmd
benchmark command
echo-server command
http-benchmark command
http-server command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL