This guide showcases how to start with a basic HTTP server and progressively incorporate TCP, static file serving, and middleware for logging. This helps showcase the depth of Go’s libraries and its application in real-world scenarios and versatility.
Setting Up Your Go Environment
Ensure Go is installed on your system by downloading it from the official website and verify the installation with go version.
Writing Your First Web Server in Go
Start with a simple HTTP server that responds with “Hello, World!” for every request.
main.go
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
}
func main() {
http.HandleFunc("/", handler)
fmt.Println("Starting server at port 8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
Run your server with go run main.go, and visit http://localhost:8080 to see your “Hello, World!” message.
Networking with Go: TCP Server and Client
You can extend your Go web server to include L4 capabilities, building a simple TCP server and client.
TCP Server Example:
package main
import (
"bufio"
"fmt"
"net"
)
func handleConnection(conn net.Conn) {
defer conn.Close()
reader := bufio.NewReader(conn)
line, err := reader.ReadString('\n')
if err != nil {
fmt.Println("Error reading:", err)
return
}
fmt.Printf("Received: %s", line)
fmt.Fprintf(conn, "Echo: %s", line)
}
func main() {
listener, err := net.Listen("tcp", ":8081")
if err != nil {
panic(err)
}
defer listener.Close()
fmt.Println("TCP Server listening on port 8081")
for {
conn, err := listener.Accept()
if err != nil {
fmt.Println("Error accepting:", err)
continue
}
go handleConnection(conn)
}
}
TCP Client Example:
Connects to the TCP server, sends a message, and receives an echo response.
package main
import (
"bufio"
"fmt"
"net"
"os"
)
func main() {
conn, err := net.Dial("tcp", "localhost:8081")
if err != nil {
panic(err)
}
defer conn.Close()
fmt.Println("Type your message:")
reader := bufio.NewReader(os.Stdin)
text, _ := reader.ReadString('\n')
fmt.Fprintf(conn, text)
message, _ := bufio.NewReader(conn).ReadString('\n')
fmt.Print("Server echo: " + message)
}
Advanced Web Server: Handling Routes, Serving Static Files, and Logging Middleware
Expand the web server to handle multiple / different routes, serve static files, and log requests with middleware.
Enhanced Web Server:
package main
import (
"fmt"
"log"
"net/http"
"time"
)
func main() {
http.HandleFunc("/", homeHandler)
http.HandleFunc("/about", aboutHandler)
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
http.Handle("/log/", loggingMiddleware(http.HandlerFunc(logHandler)))
fmt.Println("Enhanced server running on port 8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Welcome to the Home Page!")
}
func aboutHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "About Page.")
}
func logHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "This request was logged.")
}
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
defer log.Printf("%s %s %v", r.Method, r.URL.Path, time.Since(start))
next.ServeHTTP(w, r)
})
}
This guide covered the (very) basics of web and network programming in Go, starting from a simple web server to incorporating advanced features like L4 networking, static file serving, and middleware for logging. Go’s straightforward syntax and its powerful libraries, makes it an excellent choice for developers looking to build efficient, scalable web / network applications. Whether you’re new to Go or looking to expand your skills, this guide should hopefully provide a solid foundation for developing robust Go applications that can handle web and network tasks.