Introduction
Networking is a crucial part of many applications, and Go provides robust support for network programming through its net
package. In this chapter, you will learn the basics of networking in Go, including creating TCP and UDP clients and servers, handling HTTP requests, and using concurrency with goroutines for efficient network communication.
TCP Networking
TCP Server
A TCP server listens for incoming connections on a specified port and handles them as they arrive.
Example: Basic TCP Server
package main
import (
"bufio"
"fmt"
"log"
"net"
)
func handleConnection(conn net.Conn) {
defer conn.Close()
reader := bufio.NewReader(conn)
for {
message, err := reader.ReadString('\n')
if err != nil {
log.Println("Connection closed")
return
}
fmt.Print("Message received: ", message)
conn.Write([]byte("Message received\n"))
}
}
func main() {
ln, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatal(err)
}
defer ln.Close()
log.Println("Server started on port 8080")
for {
conn, err := ln.Accept()
if err != nil {
log.Println(err)
continue
}
go handleConnection(conn)
}
}
TCP Client
A TCP client connects to a TCP server and communicates by sending and receiving messages.
Example: Basic TCP Client
package main
import (
"bufio"
"fmt"
"log"
"net"
"os"
)
func main() {
conn, err := net.Dial("tcp", "localhost:8080")
if err != nil {
log.Fatal(err)
}
defer conn.Close()
reader := bufio.NewReader(os.Stdin)
for {
fmt.Print("Enter message: ")
message, _ := reader.ReadString('\n')
conn.Write([]byte(message))
response, _ := bufio.NewReader(conn).ReadString('\n')
fmt.Print("Response: ", response)
}
}
UDP Networking
UDP Server
A UDP server listens for incoming datagrams on a specified port.
Example: Basic UDP Server
package main
import (
"fmt"
"log"
"net"
)
func main() {
addr := net.UDPAddr{
Port: 8080,
IP: net.ParseIP("127.0.0.1"),
}
conn, err := net.ListenUDP("udp", &addr)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
buffer := make([]byte, 1024)
for {
n, clientAddr, err := conn.ReadFromUDP(buffer)
if err != nil {
log.Println(err)
continue
}
fmt.Printf("Received %s from %s\n", string(buffer[:n]), clientAddr)
conn.WriteToUDP([]byte("Message received\n"), clientAddr)
}
}
UDP Client
A UDP client sends datagrams to a UDP server and waits for responses.
Example: Basic UDP Client
package main
import (
"bufio"
"fmt"
"log"
"net"
"os"
)
func main() {
addr := net.UDPAddr{
Port: 8080,
IP: net.ParseIP("127.0.0.1"),
}
conn, err := net.DialUDP("udp", nil, &addr)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
reader := bufio.NewReader(os.Stdin)
for {
fmt.Print("Enter message: ")
message, _ := reader.ReadString('\n')
conn.Write([]byte(message))
buffer := make([]byte, 1024)
n, _, _ := conn.ReadFromUDP(buffer)
fmt.Print("Response: ", string(buffer[:n]))
}
}
HTTP Networking
Go’s net/http
package provides a high-level API for building HTTP servers and clients.
HTTP Server
An HTTP server listens for HTTP requests and responds with appropriate data.
Example: Basic HTTP Server
package main
import (
"fmt"
"log"
"net/http"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, World!")
}
func main() {
http.HandleFunc("/", helloHandler)
log.Println("Starting server on :8080")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
}
HTTP Client
An HTTP client sends HTTP requests to a server and processes the responses.
Example: Basic HTTP Client
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
resp, err := http.Get("http://localhost:8080")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(body))
}
Concurrency with Goroutines
Using goroutines, you can handle multiple network connections concurrently, improving the efficiency and scalability of your network applications.
Example: Concurrent TCP Server
Example:
package main
import (
"bufio"
"fmt"
"log"
"net"
)
func handleConnection(conn net.Conn) {
defer conn.Close()
reader := bufio.NewReader(conn)
for {
message, err := reader.ReadString('\n')
if err != nil {
log.Println("Connection closed")
return
}
fmt.Print("Message received: ", message)
conn.Write([]byte("Message received\n"))
}
}
func main() {
ln, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatal(err)
}
defer ln.Close()
log.Println("Server started on port 8080")
for {
conn, err := ln.Accept()
if err != nil {
log.Println(err)
continue
}
go handleConnection(conn) // Handle each connection in a new goroutine
}
}
Conclusion
Go’s net
and net/http
packages provide powerful tools for building networked applications. Whether you are working with TCP, UDP, or HTTP, Go’s concurrency model with goroutines allows you to handle multiple connections efficiently. By understanding these basic networking concepts and examples, you can build robust and scalable network applications in Go.