Пакет net встроенных функций и типов языка Go
Categories:
Пакет обеспечивает доступ к примитивам низкоуровневых сетей, большинству клиентов понадобится только базовый интерфейс, предоставляемый функциями Dial, Listen и Accept и связанными интерфейсами Conn и Listener. Пакет crypto/tls использует те же интерфейсы и похожие функции Dial и Listen.
Функция Dial подключается к серверу:
conn, err := net.Dial("tcp", "golang.org:80")
if err != nil {
// handle error
}
fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")
status, err := bufio.NewReader(conn).ReadString('\n')
// ...
Функция Listen создает серверы:
ln, err := net.Listen("tcp", ":8080")
if err != nil {
// handle error
}
for {
conn, err := ln.Accept()
if err != nil {
// handle error
}
go handleConnection(conn)
}
Разрешение имен (Name Resolution)
Метод разрешения доменных имен (DNS) в пакете net
зависит от операционной системы. Функции, такие как Dial
, используют разрешение имен косвенно, а функции вроде LookupHost
и LookupAddr
делают это напрямую.
На Unix-системах
Ресолвер имеет два варианта работы:
- Чистый Go-ресолвер – отправляет DNS-запросы напрямую к серверам, указанным в
/etc/resolv.conf
. - CGO-ресолвер – использует системные вызовы C (
getaddrinfo
,getnameinfo
).
Чистый Go-ресолвер предпочтительнее, потому что:
- Заблокированный DNS-запрос потребляет только горутину (легковесный поток Go).
- Заблокированный вызов C занимает системный поток ОС (более затратно).
Когда используется CGO-ресолвер?
- На системах, где запрещены прямые DNS-запросы (например, macOS).
- Если заданы переменные окружения:
LOCALDOMAIN
(даже пустая),RES_OPTIONS
,HOSTALIASES
(не пустые),ASR_CONFIG
(только OpenBSD).
- Если
/etc/resolv.conf
или/etc/nsswitch.conf
требуют функциональности, не реализованной в Go.
Лимит на CGO-запросы
Во всех системах (кроме Plan 9) действует ограничение в 500 одновременных CGO-запросов, чтобы избежать исчерпания системных потоков.
Управление выбором ресолвера
Можно переопределить выбор ресолвера через переменную окружения GODEBUG
:
export GODEBUG=netdns=go # принудительно использовать чистый Go-ресолвер
export GODEBUG=netdns=cgo # принудительно использовать нативный (CGO) ресолвер
Также можно задать поведение при сборке через теги:
netgo
– только Go-ресолвер (CGO полностью отключен).netcgo
– оба ресолвера, но CGO имеет приоритет (можно переопределить черезGODEBUG=netdns=go
).
Отладочная информация
Если установить GODEBUG=netdns=1
, ресолвер будет выводить отладочную информацию. Можно комбинировать:
export GODEBUG=netdns=go+1 # принудительно Go + отладка
EDNS0 и проблемы с роутерами
Go-ресолвер по умолчанию отправляет EDNS0-заголовок, чтобы запрашивать большие DNS-пакеты. Это может вызывать ошибки на некоторых модемах/роутерах. Отключить:
export GODEBUG=netedns0=0
Особенности на разных ОС
- macOS:
- Если Go-код собран с
-buildmode=c-archive
, для линковки в C-программу требуется флаг-lresolv
.
- Если Go-код собран с
- Plan 9:
- Ресолвер всегда использует
/net/cs
и/net/dns
.
- Ресолвер всегда использует
- Windows (Go 1.18.x и старше):
- Всегда используются C-функции (
GetAddrInfo
,DnsQuery
).
- Всегда используются C-функции (
Ключевые термины
- Ресолвер (Resolver) – механизм преобразования доменных имен в IP-адреса.
- CGO – вызовы C-кода из Go.
- EDNS0 – расширение DNS, позволяющее увеличить размер пакета.
- GODEBUG – переменная окружения для настройки поведения Go-рантайма.