Skip to content

net

Le package standard net de Go est une bibliothèque très puissante. Il fournit des fonctionnalités pour gérer les communications réseau, les adresses IP, la résolution DNS, les protocoles TCP/UDP, le protocole HTTP et d'autres tâches courantes. Grâce aux caractéristiques concurrentes natives de Go, le traitement des E/S réseau en Go est très concis et efficace.

Résolution d'adresses

Go fournit quatre fonctions pour résoudre les adresses réseau, expliquées ci-dessous une par une.

Adresse MAC

Signature

go
func ParseMAC(s string) (hw HardwareAddr, err error)

Exemple

go
package main

import (
  "fmt"
  "net"
)

func main() {
  hw, err := net.ParseMAC("00:1A:2B:3C:4D:5E")
  if err != nil {
    panic(err)
  }
  fmt.Println(hw)
}

CIDR

Signature

go
func ParseCIDR(s string) (IP, *IPNet, error)

Exemple

go
package main

import (
    "fmt"
    "log"
    "net"
)

func main() {
    ipv4Addr, ipv4Net, err := net.ParseCIDR("192.0.2.1/24")
    if err != nil {
       log.Fatal(err)
    }
    fmt.Println(ipv4Addr)
    fmt.Println(ipv4Net)
}

Adresse IP

La résolution d'adresses IP supporte ipv4 et ipv6, la signature de la fonction est la suivante

go
func ResolveIPAddr(network, address string) (*IPAddr, error)

Exemple d'utilisation

go
package main

import (
  "fmt"
  "net"
)

func main() {
  ipv4Addr, err := net.ResolveIPAddr("ip4", "192.168.2.1")
  if err != nil {
    panic(err)
  }
  fmt.Println(ipv4Addr)

  ipv6Addr, err := net.ResolveIPAddr("ip6", "2001:0db8:85a3:0000:0000:8a2e:0370:7334")
  if err != nil {
    panic(err)
  }
  fmt.Println(ipv6Addr)
}

Adresse TCP

L'adresse TCP supporte tcp4 et tcp6, la signature est la suivante

go
func ResolveTCPAddr(network, address string) (*TCPAddr, error)

Exemple d'utilisation

go
package main

import (
  "fmt"
  "net"
)

func main() {
  tcp4Addr, err := net.ResolveTCPAddr("tcp4", "0.0.0.0:2020")
  if err != nil {
    panic(err)
  }
  fmt.Println(tcp4Addr)
  tcp6Addr, err := net.ResolveTCPAddr("tcp6", "[::1]:8080")
  if err != nil {
    panic(err)
  }
  fmt.Println(tcp6Addr)
}

Adresse UDP

L'adresse UDP supporte udp4 et udp6, la signature est la suivante

go
func ResolveUDPAddr(network, address string) (*UDPAddr, error)

Exemple d'utilisation

go
package main

import (
  "fmt"
  "net"
)

func main() {
  udp4Addr, err := net.ResolveUDPAddr("udp4", "0.0.0.0:2020")
  if err != nil {
    panic(err)
  }
  fmt.Println(udp4Addr)
  udp6Addr, err := net.ResolveUDPAddr("udp6", "[::1]:8080")
  if err != nil {
    panic(err)
  }
  fmt.Println(udp6Addr)
}

Adresse Unix

L'adresse Unix supporte unix, unixgram, unixpacket, la signature est la suivante

go
func ResolveUnixAddr(network, address string) (*UnixAddr, error)

Exemple d'utilisation

go
package main

import (
    "fmt"
    "net"
)

func main() {
    unixAddr, err := net.ResolveUnixAddr("unix", "/tmp/mysocket")
    if err != nil {
       panic(err)
    }
    fmt.Println(unixAddr)
}

DNS

Go fournit également de nombreuses fonctions pour les requêtes DNS. L'exemple suivant montre comment résoudre l'adresse IP d'un nom de domaine

go
package main

import (
  "fmt"
  "net"
)

func main() {
  addrs, err := net.LookupHost("github.com")
  if err != nil {
    panic(err)
  }
  fmt.Println(addrs)
}

Requête d'enregistrements

go
package main

import (
  "fmt"
  "net"
)

func main() {
  mxs, err := net.LookupMX("github.com")
  if err != nil {
    panic(err)
  }
  fmt.Println(mxs)
}

Programmation réseau

La logique de programmation TCP est très simple. Pour le client, il s'agit de :

  1. Établir une connexion
  2. Envoyer ou lire des données
  3. Quitter

Pour le serveur, il s'agit de :

  1. Écouter une adresse
  2. Obtenir une connexion
  3. Créer une nouvelle goroutine pour traiter cette connexion

Voici un exemple simple, code client

go
package main

import (
  "net"
)

func main() {
  // Établir une connexion
  conn, err := net.Dial("tcp", "0.0.0.0:1234")
  if err != nil {
    panic(err)
  }
  defer conn.Close()

  // Envoyer des données
  for i := range 10 {
    _, err := conn.Write([]byte{'a' + byte(i)})
    if err != nil {
      panic(err)
    }
  }
}

Code serveur

go
package main

import (
  "errors"
  "fmt"
  "io"
  "net"
  "sync"
)

func main() {
  // Écouter l'adresse
  listener, err := net.Listen("tcp", "0.0.0.0:1234")
  if err != nil {
    panic(err)
  }
  defer listener.Close()

  var wg sync.WaitGroup

  for {
    // Attendre bloquant la prochaine connexion
    conn, err := listener.Accept()
    if err != nil {
      panic(err)
    }

    // Démarrer une nouvelle goroutine pour traiter cette connexion de manière asynchrone
    wg.Add(1)
    go func() {
      defer wg.Done()
      buf := make([]byte, 4096)
      for {
        // Lire les données depuis la connexion
        n, err := conn.Read(buf)
        if errors.Is(err, io.EOF) {
          break
        } else if err != nil {
          panic(err)
        }

        data := string(buf[:n])
        fmt.Println(data)
      }
    }()
  }

  wg.Wait()
}

Le client envoie des données, le serveur les reçoit. Cet exemple est très simple. Lorsqu'une nouvelle connexion est établie sur le serveur, il suffit de démarrer une nouvelle goroutine pour la traiter sans bloquer. L'écriture UDP est globalement similaire.

Golang by www.golangdev.cn edit