MySQL Java JavaScript PHP Python HTML-CSS C-sharp C++ Go

Programare de rețea

Una dintre posibilitățile cheie ale limbajului Go este capacitatea de a lucra cu servicii de rețea: trimiterea de cereri către resursele din rețea și, invers, procesarea cererilor primite. Funcționalitatea principală pentru lucrul cu rețeaua este oferită de pachetul net. Acest pachet furnizează diferite primitive de rețea de nivel scăzut, prin intermediul cărora se face interacțiunea în rețea.

Trimiterea cererilor

Pentru a trimite cereri către resursele din rețea se utilizează funcția net.Dial():

func Dial(network, address string) (Conn, error)

Această funcție primește doi parametri: network - tipul protocolului și address - adresa resursei.

Există următoarele tipuri de protocoale:

  • tcp, tcp4, tcp6: protocolul TCP. tcp reprezintă implicit tcp4, iar cifra de la final indică ce tip de adrese va fi utilizat: IPv4 sau IPv6
  • udp, udp4, udp6: protocolul UDP. udp reprezintă implicit udp4
  • ip, ip4, ip6: protocolul IP. ip reprezintă implicit ip4
  • unix, unixgram, unixpacket: socketuri Unix

Al doilea parametru reprezintă adresa rețelei resursei (pentru adresele din rețeaua Internet, aceasta este domeniul). Poate fi o adresă rețea numerică, de exemplu, "127.0.0.1". Poate include specificarea unui port, de exemplu, "127.0.0.1:80". De asemenea, poate fi o adresă în format IPv6, de exemplu, "::1" sau "[2516:b7f0:3421:b16::71]:80".

Funcția returnează un obiect care implementează interfața net.Conn. Această interfață, la rândul său, aplică interfețele io.Reader și io.Writer, ceea ce înseamnă că poate fi folosită ca un flux pentru citire și scriere. Pachetul net furnizează implementări de bază ale acestei interfețe sub forma tipurilor IPConn, UDPConn, TCPConn. În funcție de protocolul utilizat, se returnează tipul corespunzător.

Astfel, folosind această funcție, putem trimite cereri prin protocoalele TCP și UDP. De exemplu:

package main
import (
    "fmt"
    "os"
    "net"
    "io"
)

func main() {
    httpRequest := "GET / HTTP/1.1\n" + 
        "Host: golang.org\n\n"
    conn, err := net.Dial("tcp", "golang.org:80") 
    if err != nil { 
        fmt.Println(err) 
        return
    } 
    defer conn.Close() 
  
    if _, err = conn.Write([]byte(httpRequest)); err != nil { 
        fmt.Println(err) 
        return
    }
  
    io.Copy(os.Stdout, conn) 
    fmt.Println("Done")
}

În acest caz, efectiv facem o cerere către resursa web golang.org. Deoarece net.Conn implementează interfețele io.Reader și io.Writer, putem scrie date în acest obiect — practic trimitem date prin rețea — și putem citi din acesta — primim date din rețea. De exemplu, conn.Write([]byte(httpRequest)) trimite datele, care aici sunt reprezentate de variabila httpRequest. Deoarece metoda Write trimite un slice de octeți, orice date trebuie transformate într-un slice de octeți.

Ca orice obiect io.Reader, putem transmite net.Conn în funcția io.Copy și să citim datele primite prin rețea, de exemplu, pe consolă: io.Copy(os.Stdout, conn).

net.Dial și TCP, trimiterea unei cereri în Golang

Merită menționat că exemplul de mai sus trimite o cerere către o resursă de rețea din Internet prin protocolul TCP. Totuși, pentru acest scop, este mult mai convenabil să utilizăm funcționalitățile pachetului net/http, care este destinat special pentru protocolul HTTP, ce funcționează deasupra TCP.