Go Networking

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.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top