La llamada subyacente de la función Dial
En el último tutorial , presentamos que el lenguaje Go puede Dial()
establecer conexiones de red a través de funciones. De hecho, la Dial()
función es una dialTCP()
, dialUDP()
, dialIP()
y dialUnix()
embalaje, que puede ser rastreado por Dial()
la función de fuente para ver la conexión real se establece por el subyacente dialSingle()
funciones realizadas:
dialSingle()
La función llama a la función de establecimiento de conexión correspondiente obteniendo el tipo de protocolo de red de los parámetros entrantes y devuelve el objeto de conexión. Mirando más abajo, puede ver que estas funciones subyacentes eventualmente llaman a las funciones del paquete syscall para Socket()
interactuar con la API de Socket del sistema operativo de la plataforma correspondiente para establecer una conexión de red. Para diferentes protocolos de comunicación, se establecen diferentes tipos de conexión:
Lo que domain
representa el dominio de comunicación, admite IPv4, IPv6 y Unix, y los valores constantes correspondientes son syscall.AF_INET
, syscall.AF_INET6
y respectivamente syscall.AF_UNIX
.
Nota: IPv4 e IPv6 representan la cuarta y sexta ediciones de la red de protocolo IP, respectivamente. Unix se refiere al dominio de comunicación único en un sistema operativo similar a Unix. En la misma computadora con dicho sistema operativo, las aplicaciones pueden basarse en Este dominio establece una conexión de socket.
typ
El tipo de socket representa, como la constante de tipo de socket TCP es la correspondiente syscall.SOCK_STREAM
(comunicación orientada a la conexión), la constante de tipo de socket UDP es la correspondiente syscall.SOCK_DGRAM
(comunicación sin conexión), además del soporte syscall.SOCK_RAW
y syscall.SOCK_SEQPACKET
dos tipos, SOCK_RAW
de hecho, los paquetes IP originales SOCK_SEQPACKET
y SOCK_STREAM
similares , ambos están orientados a la conexión, excepto que el primero tiene un límite de mensaje y transmite paquetes de datos en lugar de flujos de bytes. Usualmente usamos SOCK_STREAM
y SOCK_DGRAM
principalmente.
El último parámetro proto
representa el protocolo de comunicación y, por lo general 0
, tiene el valor predeterminado , porque el valor puede ser determinado por los dos primeros parámetros. Por ejemplo, cuando los dos primeros valores de parámetro son syscall.AF_INET
y respectivamente syscall.SOCK_DGRAM
, se seleccionará UDP como protocolo de comunicación, y los dos primeros valores de los parámetros son respectivamente como syscall.AF_INET6
y syscall.SOCK_STREAM
cuándo seleccionará TCP como protocolo de comunicación.
Por supuesto, cuando escribimos programas de red en Go, no necesitamos preocuparnos en absoluto por estos detalles de implementación de bajo nivel, solo necesitamos llamar a la Dial
función y pasar los parámetros correspondientes.
Manejo del tiempo de espera de la red
El tiempo de espera de la red está contenido en varios enlaces, como el tiempo de espera de la conexión, el tiempo de espera de la solicitud y el tiempo de espera de la respuesta. Veamos primero el tiempo de espera de la conexión.
Tiempo de conexión agotado
Cuando utilice una Dial
función para establecer una conexión de red, puede utilizar la función proporcionada por el paquete net para DialTimeout
pasar activamente parámetros de tiempo de espera adicionales para establecer una conexión. El prototipo de la función es el siguiente:
func DialTimeout(network, address string, timeout time.Duration) (Conn, error) {
d := Dialer{Timeout: timeout}
return d.Dial(network, address)
}
Y Dial
la llamada a la función, como, solo campos de tiempo de espera, si usa Dial
la función, el tiempo de espera de conexión predeterminado será manejado por el sistema operativo proporciona el mecanismo para conexiones TCP, generalmente alrededor de 3 minutos, que para nuestro programa, puede ser demasiado tiempo, y esta vez, puede DialTimeout
establecer una conexión con el código de ejemplo del tutorialtcp.go
, por ejemplo, si la solicitud se cerró a un nombre de dominio extranjero, por ejemplo facebook.com
, es posible que el programa no responda durante mucho tiempo, establecerá una conexión de red a ajuste el código de la siguiente manera:
// 建立网络连接
conn, err := net.DialTimeout("tcp", service, 3 * time.Second)
Solicite nuevamente, y se devolverá un error de tiempo de espera después de 3 segundos para salir:
Tiempo de espera de solicitud y respuesta
Después de usar la función Dial
o DialTimeout
para establecer una conexión de red con éxito, devolverá el net.Conn
objeto, y luego podemos realizar operaciones de lectura y escritura en el objeto para lograr la solicitud y la respuesta. El tiempo de espera de esta parte se puede establecer mediante Conn
los siguientes tres métodos previsto:
SetDeadline(t time.Time) error
SetReadDeadline(t time.Time) error
SetWriteDeadline(t time.Time) error
Podemos SetDeadline
establecer un tiempo de espera unificado de lectura y escritura, o configurar el tiempo de espera de lectura y escritura SetReadDeadline
y SetWriteDeadline
respectivamente. Tenga en cuenta que estos tres métodos pasan valores de tiempo absolutos, no longitudes de tiempo relativas:
// 设置读写超时时间
err = conn.SetDeadline(time.Now().Add(5 * time.Second))
checkError(err)
Más funciones de herramientas
Además, el paquete net también proporciona una serie de funciones de herramientas. El uso razonable de estas funciones puede mejorar de manera efectiva la eficiencia del desarrollo y garantizar mejor la calidad del programa.
Por ejemplo, puede ParseIP
verificar la validez de la dirección IP a través de la función:
func net.ParseIP()
Por IPv4Mask
la creación de una máscara de subred:
func IPv4Mask(a, b, c, d byte) IPMask
Al DefaultMask
obtener la máscara de subred predeterminada:
func (ip IP) DefaultMask() IPMask
Y según el nombre de dominio para encontrar la dirección IP correspondiente:
func ResolveIPAddr(net, addr string) (*IPAddr, error)
func LookupHost(name string) (cname string, addrs []string, err error)