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
func ParseMAC(s string) (hw HardwareAddr, err error)Örnek
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
func ParseCIDR(s string) (IP, *IPNet, error)Örnek
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
func ResolveIPAddr(network, address string) (*IPAddr, error)Kullanım örneği aşağıdaki gibidir
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
func ResolveTCPAddr(network, address string) (*TCPAddr, error)Kullanım örneği aşağıdaki gibidir
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
func ResolveUDPAddr(network, address string) (*UDPAddr, error)Kullanım örneği aşağıdaki gibidir
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
func ResolveUnixAddr(network, address string) (*UnixAddr, error)Kullanım örneği aşağıdaki gibidir
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
package main
import (
"fmt"
"net"
)
func main() {
addrs, err := net.LookupHost("github.com")
if err != nil {
panic(err)
}
fmt.Println(addrs)
}MX kaydı sorgulama
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
- Bağlantı kur
- Veri gönder veya oku
- Çık
Sunucu için ise
- Adresi dinle
- Bağlantıyı al
- Bu bağlantıyı işlemek için yeni bir goroutine oluştur
Aşağıda basit bir örnek bulunmaktadır, istemci kodu
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
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.
