Go Socket Programming (2): la implementación subyacente y el manejo del tiempo de espera de la función Dial

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:

Implementación subyacente de la función Net.DialSingle

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:

Implementación del catálogo de funciones syscall.Socket

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

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:

Manejo del tiempo de espera de la conexión de red

Tiempo de espera de solicitud y respuesta

Después de usar la   función Dial o  DialTimeoutpara 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  SetWriteDeadlinerespectivamente. 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)

 

Supongo que te gusta

Origin blog.csdn.net/wxy_csdn_world/article/details/107445220
Recomendado
Clasificación