Skip to content

net

Go dilinin net standart kütüphanesi oldukça güçlü bir kütüphanedir ve ağ iletişimi, IP adresleri, DNS çözümlemesi, TCP/UDP protokolleri, HTTP protokolü gibi yaygın görevleri işleme işlevleri sağlar. Go dilinin eşzamanlılık özellikleri sayesinde, Go ağ IO işlemlerinde oldukça temiz ve verimli çalışır.

Adres Çözümleme

Go ağ adreslerini çözümlemek için dört fonksiyon sağlar, aşağıda her birini açıklayacağız.

MAC Adresi

İmza

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

Örnek

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

İmza

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

Örnek

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)
}

IP Adresi

IP adresi ipv4 ve ipv6 çözümlemesini destekler, fonksiyon imzası aşağıdaki gibidir

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

Kullanım örneği aşağıdaki gibidir

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)
}

TCP Adresi

TCP adresi tcp4 ve tcp6'yı destekler, imza aşağıdaki gibidir

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

Kullanım örneği aşağıdaki gibidir

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)
}

UDP Adresi

UDP adresi udp4 ve udp6'yı destekler, imza aşağıdaki gibidir

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

Kullanım örneği aşağıdaki gibidir

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)
}

Unix Adresi

Unix adresi unix, unixgram ve unixpacket'ı destekler, imza aşağıdaki gibidir

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

Kullanım örneği aşağıdaki gibidir

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 ayrıca DNS sorguları için birçok fonksiyon sağlar, aşağıda bir örnek alan adının IP adresini çözümlemektedir

go
package main

import (
  "fmt"
  "net"
)

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

MX kaydı sorgulama

go
package main

import (
  "fmt"
  "net"
)

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

Ağ Programlama

tcp programlamanın mantığı oldukça basittir, istemci için

  1. Bağlantı kur
  2. Veri gönder veya oku
  3. Çık

Sunucu için ise

  1. Adresi dinle
  2. Bağlantıyı al
  3. Bu bağlantıyı işlemek için yeni bir goroutine oluştur

Aşağıda basit bir örnek bulunmaktadır, istemci kodu

go
package main

import (
  "net"
)

func main() {
  // Bağlantı kur
  conn, err := net.Dial("tcp", "0.0.0.0:1234")
  if err != nil {
    panic(err)
  }
  defer conn.Close()

  // Veri gönder
  for i := range 10 {
    _, err := conn.Write([]byte{'a' + byte(i)})
    if err != nil {
      panic(err)
    }
  }
}

Sunucu kodu

go
package main

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

func main() {
  // Adresi dinle
  listener, err := net.Listen("tcp", "0.0.0.0:1234")
  if err != nil {
    panic(err)
  }
  defer listener.Close()

  var wg sync.WaitGroup

  for {
    // Bir sonraki bağlantının kurulmasını bekle
    conn, err := listener.Accept()
    if err != nil {
      panic(err)
    }

    // Bu bağlantıyı asenkron olarak işlemek için yeni bir goroutine başlat
    wg.Add(1)
    go func() {
      defer wg.Done()
      buf := make([]byte, 4096)
      for {
        // Bağlantıdan veri oku
        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()
}

İstemci veri gönderir, sunucu veri alır, bu örnek oldukça basittir, sunucu yeni bağlantı kurduğunda sadece yeni bir goroutine başlatarak işleyebilir, engelleme yapmaz, UDP de büyük ölçüde benzer şekilde yazılır.

Golang by www.golangdev.cn edit