Networking
TCP/UDP
Section titled “TCP/UDP”TCP Connections
Section titled “TCP Connections”The net package provides TCP support via net.Dial and net.Listen:
// Clientconn, err := net.Dial("tcp", "localhost:8080")if err != nil { log.Fatal(err)}defer conn.Close()
_, err = conn.Write([]byte("hello"))if err != nil { log.Fatal(err)}
buf := make([]byte, 1024)n, err := conn.Read(buf)fmt.Println(string(buf[:n]))// Serverlistener, err := net.Listen("tcp", ":8080")if err != nil { log.Fatal(err)}defer listener.Close()
for { conn, err := listener.Accept() if err != nil { log.Println(err) continue } go handleConnection(conn)}Timeouts and Deadlines
Section titled “Timeouts and Deadlines”Always set timeouts. Without them, reads and writes can block indefinitely:
conn, err := net.DialTimeout("tcp", "localhost:8080", 5*time.Second)
conn.SetReadDeadline(time.Now().Add(10 * time.Second))conn.SetWriteDeadline(time.Now().Add(10 * time.Second))UDP Packets
Section titled “UDP Packets”addr, err := net.ResolveUDPAddr("udp", "localhost:9090")conn, err := net.DialUDP("udp", nil, addr)
conn.Write([]byte("hello"))buf := make([]byte, 1024)n, _, err := conn.ReadFromUDP(buf)HTTP Client
Section titled “HTTP Client”Advanced http.Client
Section titled “Advanced http.Client”client := &http.Client{ Timeout: 30 * time.Second, Transport: &http.Transport{ MaxIdleConns: 100, MaxIdleConnsPerHost: 10, IdleConnTimeout: 90 * time.Second, TLSClientConfig: &tls.Config{ MinVersion: tls.VersionTLS12, }, },}Timeouts
Section titled “Timeouts”Three separate timeout controls:
client := &http.Client{ Timeout: 30 * time.Second, // overall request timeout Transport: &http.Transport{ DialContext: (&net.Dialer{ Timeout: 5 * time.Second, // connection timeout }).DialContext, TLSHandshakeTimeout: 10 * time.Second, // TLS handshake ResponseHeaderTimeout: 10 * time.Second, // first response byte },}Redirects and Cookies
Section titled “Redirects and Cookies”client := &http.Client{ CheckRedirect: func(req *http.Request, via []*http.Request) error { if len(via) >= 5 { return fmt.Errorf("stopped after 5 redirects") } return nil }, Jar: http.CookieJar(nil),}HTTP Server
Section titled “HTTP Server”Advanced Routing
Section titled “Advanced Routing”mux := http.NewServeMux()mux.HandleFunc("/users/", usersHandler)mux.HandleFunc("/users/create", createUserHandler)mux.HandleFunc("/health", healthHandler)
srv := &http.Server{ Addr: ":8080", Handler: mux,}srv.ListenAndServe()Note: ServeMux uses longest-prefix matching. /users/ matches /users/123 but /users matches only exactly /users.
Middleware Chains
Section titled “Middleware Chains”type Middleware func(http.Handler) http.Handler
func Logging(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() next.ServeHTTP(w, r) log.Printf("%s %s %v", r.Method, r.URL.Path, time.Since(start)) })}
func Auth(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("Authorization") if token == "" { http.Error(w, "unauthorized", http.StatusUnauthorized) return } next.ServeHTTP(w, r) })}
func Chain(h http.Handler, mws ...Middleware) http.Handler { for i := len(mws) - 1; i >= 0; i-- { h = mws[i](h) } return h}
handler := Chain(mux, Logging, Auth)Graceful Shutdown
Section titled “Graceful Shutdown”srv := &http.Server{Addr: ":8080", Handler: mux}
go func() { sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) <-sigCh
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() srv.Shutdown(ctx)}()
srv.ListenAndServe()Context Propagation
Section titled “Context Propagation”Always propagate context.Context through handlers:
func handler(w http.ResponseWriter, r *http.Request) { ctx := r.Context() ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel()
data, err := fetchData(ctx) // ...}WebSockets
Section titled “WebSockets”Using gorilla/websocket:
var upgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, CheckOrigin: func(r *http.Request) bool { return true },}
func wsHandler(w http.ResponseWriter, r *http.Request) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Println(err) return } defer conn.Close()
for { msgType, msg, err := conn.ReadMessage() if err != nil { break } err = conn.WriteMessage(msgType, msg) if err != nil { break } }}Ping/Pong
Section titled “Ping/Pong”func readPump(conn *websocket.Conn) { defer conn.Close() conn.SetReadLimit(512) conn.SetReadDeadline(time.Now().Add(60 * time.Second)) conn.SetPongHandler(func(string) error { conn.SetReadDeadline(time.Now().Add(60 * time.Second)) return nil }) for { _, _, err := conn.ReadMessage() if err != nil { return } }}
func writePump(conn *websocket.Conn) { ticker := time.NewTicker(54 * time.Second) defer ticker.Stop() for { select { case <-ticker.C: if err := conn.WriteMessage(websocket.PingMessage, nil); err != nil { return } } }}Protocol Buffers
Section titled “Protocol Buffers”service UserService { rpc GetUser (GetUserRequest) returns (UserResponse); rpc CreateUser (CreateUserRequest) returns (UserResponse);}
message GetUserRequest { string id = 1;}
message UserResponse { string id = 1; string name = 2; string email = 3;}Server Implementation
Section titled “Server Implementation”type server struct { pb.UnimplementedUserServiceServer repo Repository}
func (s *server) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.UserResponse, error) { user, err := s.repo.GetByID(ctx, req.Id) if err != nil { return nil, status.Errorf(codes.NotFound, "user %q not found", req.Id) } return &pb.UserResponse{Id: user.ID, Name: user.Name, Email: user.Email}, nil}Client
Section titled “Client”conn, err := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithTimeout(5*time.Second),)defer conn.Close()
client := pb.NewUserServiceClient(conn)resp, err := client.GetUser(ctx, &pb.GetUserRequest{Id: "123"})Custom DNS Lookups
Section titled “Custom DNS Lookups”resolver := &net.Resolver{ PreferGo: true, Dial: func(ctx context.Context, network, address string) (net.Conn, error) { d := net.Dialer{Timeout: 5 * time.Second} return d.DialContext(ctx, "udp", "8.8.8.8:53") },}
ips, err := resolver.LookupHost(ctx, "example.com")Reverse Lookup
Section titled “Reverse Lookup”names, err := net.LookupAddr("93.184.216.34")TLS/SSL
Section titled “TLS/SSL”Basic TLS Server
Section titled “Basic TLS Server”cert, err := tls.LoadX509KeyPair("server.crt", "server.key")if err != nil { log.Fatal(err)}
config := &tls.Config{ Certificates: []tls.Certificate{cert}, MinVersion: tls.VersionTLS12, CurvePreferences: []tls.CurveID{ tls.X25519, tls.CurveP256, },}
srv := &http.Server{ Addr: ":443", Handler: mux, TLSConfig: config,}srv.ListenAndServeTLS("", "")Mutual TLS (mTLS)
Section titled “Mutual TLS (mTLS)”caCert, _ := os.ReadFile("ca.crt")caPool := x509.NewCertPool()caPool.AppendCertsFromPEM(caCert)
config := &tls.Config{ ClientCAs: caPool, ClientAuth: tls.RequireAndVerifyClientCert, MinVersion: tls.VersionTLS12,}TLS Client with Custom CA
Section titled “TLS Client with Custom CA”caCert, _ := os.ReadFile("ca.crt")caPool := x509.NewCertPool()caPool.AppendCertsFromPEM(caCert)
client := &http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{ RootCAs: caPool, MinVersion: tls.VersionTLS12, }, },}Intuition
Section titled “Intuition”Networking is a postal service with delivery guarantees: TCP is like registered mail — you establish a connection (the postal route), send messages (data packets), and get confirmation of delivery. HTTP sits on top as a standardized form: everyone fills out the same template (method, headers, body). WebSockets are like keeping the phone line open instead of hanging up after each question. gRPC is a specialized courier service with a strict manifest (protobuf schema).
Why it matters: Go’s net/http is production-grade without external frameworks. Understanding the timeout layers (connection, TLS, header, body) prevents the most common production incident: a single slow client exhausting server resources.
The key insight: Every network operation needs a timeout — without deadlines, a single misbehaving peer can permanently consume a goroutine and its memory.
Common Pitfalls
Section titled “Common Pitfalls”No timeouts on connections. TCP connections without deadlines block indefinitely. Always set read/write deadlines or use
DialTimeout.Response body not closed.
resp.Bodymust always be closed withdefer resp.Body.Close(). Forgetting this leaks connections and exhausts file descriptors.Default transport in high-throughput servers. The default
http.Transporthas conservative connection pool limits. TuneMaxIdleConnsPerHostfor your workload.Not propagating context. Handler code that calls external services without context cannot be cancelled on client disconnect. Always use
r.Context().Insecure TLS in production.
insecure.NewCredentials()is for development only. Production clients must use proper CA verification.WebSocket origin check disabled.
CheckOrigin: func(r *http.Request) bool { return true }is convenient but opens the server to cross-site WebSocket hijacking. Validate origins in production.HTTP/2 server misconfiguration.
http.Serverautomatically supports HTTP/2 when usingListenAndServeTLS. Do not configure HTTP/2 viah2package separately unless you have a specific reason.
Summary
Section titled “Summary”net.Dial/net.Listenhandle TCP;net.DialUDPhandles UDP. Always set deadlines.http.Clientsupports configurable timeouts, connection pooling, redirect policies, and TLS.http.ServeMuxprovides longest-prefix routing; middleware chains wrap handlers.- Graceful shutdown via
srv.Shutdown(ctx)drains in-flight requests on signal. gorilla/websockethandles upgrade, ping/pong keepalives, and message framing.- gRPC uses protocol buffers for schema and
grpc.Dial/grpc.NewServerfor implementation. net.ResolverwithPreferGo: truebypasses the system resolver for custom DNS.crypto/tlshandles server certs, client certs (mTLS), and custom CA pools.
Worked Examples
Section titled “Worked Examples”Worked examples demonstrating the application of key concepts are covered in the detailed sub-pages linked above.
Cross-References
Section titled “Cross-References”- net/http: HTTP server and client patterns that build on networking fundamentals.
- I/O: Reader/Writer interfaces used in network stream processing.
- Interfaces: Interface-based abstraction patterns for network protocol handlers.