Pregunta

Hace poco vi un poco de código que se parecía a esto (con el calcetín como un objeto de socket, por supuesto):

sock.shutdown(socket.SHUT_RDWR)
sock.close()

¿Cuál es exactamente el propósito de llamar a shutdown en el socket y luego cerrarlo? Si hace una diferencia, este socket se está utilizando para la IO sin bloqueo.

¿Fue útil?

Solución

Aquí hay uno explicación :

  

Una vez que un socket ya no es necesario,   El programa de llamadas puede descartar el   socket mediante la aplicación de una subrutina estrecha   al descriptor de socket. Si un   La toma de entrega confiable tiene datos   asociado con él cuando un cierre toma   lugar, el sistema sigue intentando   transferencia de datos. Sin embargo, si los datos son   Aún sin entregar, el sistema descarta.   los datos. Si la solicitud   El programa no tiene uso para ningún pendiente.   datos, puede utilizar el cierre   subrutina en el zócalo antes de   cerrándolo.

Otros consejos

Llamar a close y shutdown tienen dos efectos diferentes en el socket subyacente.

Lo primero que hay que señalar es que el socket es un recurso en el sistema operativo subyacente y varios procesos pueden tener un identificador para el mismo socket subyacente.

Cuando llama a close , disminuye el número de identificadores en uno y si el número de identificadores ha llegado a cero, el socket y la conexión asociada pasan por el procedimiento de cierre normal (enviando efectivamente un FIN / EOF al peer) y el socket está desasignado.

Lo que hay que prestar atención aquí es que si el recuento de identificadores no llega a cero porque otro proceso aún tiene un identificador en el socket, entonces la conexión no se cierra y el socket no se desasigna.

Por otra parte, llamar a shutdown para leer y escribir cierra la conexión subyacente y envía un FIN / EOF al interlocutor, independientemente de la cantidad de procesos que tengan los identificadores en el socket. Sin embargo, no desasigna el zócalo y aún debe llamar para cerrar después.

Explicación de cierre y cierre: Cierre elegante (msdn)

El apagado (en su caso) indica que al otro extremo de la conexión no hay otra intención de leer o escribir en el socket. Luego, cerrar libera cualquier memoria asociada con el socket.

Omitir el apagado puede hacer que el zócalo permanezca en la pila del sistema operativo hasta que la conexión se haya cerrado correctamente.

En mi opinión, los nombres 'shutdown' y 'close' son engañosos, 'close' y 'destroy' enfatizan sus diferencias.

se menciona justo en el CÓMO de programación de sockets ( py2 / < a href = "http://docs.python.org/3/howto/sockets.html#disconnecting" rel = "noreferrer"> py3 )

  

Desconectando

     

Estrictamente hablando, se supone que debes usar shutdown en un zócalo antes de cerrar .   El shutdown es un aviso para el zócalo en el otro extremo. Dependiendo del argumento que pase, puede significar que & # 8220; I & # 8217; no voy a enviar más, pero & # 8217; seguiré escuchando & # 8221 ;, o & # 8220 ; I & # 8217; no estoy escuchando, buen viaje! & # 8221 ;.   Sin embargo, la mayoría de las bibliotecas de socket están tan acostumbradas a los programadores que no usan esta etiqueta que normalmente un close es lo mismo que shutdown (); cerrar () .   Entonces, en la mayoría de las situaciones, no es necesario un cierre explícito.

     

...

¿No está mal este código de arriba?

La llamada de cierre directamente después de la llamada de apagado podría hacer que el kernel descarte todos los buffers salientes de todos modos.

Según http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable hay que esperar entre el cierre y el cierre hasta que la lectura devuelva 0.

Shutdown (1), hace que el socket no envíe más datos

Esto es útil en

1- Lavado de búfer

2- Detección de error extraño

3- Protección segura

Permítame explicarle más, cuando envía datos de A a B, no se garantiza que sea enviado a B, solo se garantiza que se envíe al búfer de A os, que a su vez lo envía al búfer de B os

Entonces, al llamar a shutdown (1) en A, se vacía el búfer de A y se genera un error si el búfer no está vacío, es decir, los datos aún no se han enviado al interlocutor

Sin embargo, esto es irreversible, por lo que puede hacer eso después de que usted completamente ha enviado todos sus datos y quiere estar seguro de que es al menos en el mismo nivel os buffer

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top