2009-08-03 9 views
10

He leído la referencia asio boost, he reparado el tutorial y he analizado algunos de los ejemplos. Aún así, no puedo ver cómo se debe derribar un socket:¿Cómo debería uno derribar un impulso :: asio :: ip :: udp :: socket?

  1. ¿Debo llamar a close() o lo hace el destructor del socket?
  2. ¿Cuándo debería llamar a shutdown()
  3. ¿Cuáles son los efectos de shutdown()? Soy consciente de que "Deshabilita envíos o recibe", pero ¿cómo se hace? ¿Qué puedo esperar si envío o recibo usando el socket después de haber sido desactivado?
  4. ¿Qué errores se pueden esperar de cierre()

Respuesta

10

Dado que este es un multi-pregunta, haré todo lo posible para responder a cada parte a su satisfacción:

1) Ha sido mi experiencia con sockets ASIO que maneja el destructor cerrando el socket. Sin embargo, solo me he ocupado de los sockets TCP. La mejor manera de comprobar esto es simplemente mirar el código del destructor para ver si hace algo que se asemeje a un cierre. Sé que el código de Boost puede ser un poco complicado de recorrer, por lo que podría ser más fácil simplemente crear un pequeño programa de muestra que abra un socket UDP y luego lo destruya. De esa manera puede pasar por el código en un depurador para seguir la lógica.

Como los diseñadores de Boost tuvieron esto en cuenta para los sockets TCP, me cuesta imaginar que no harían lo mismo con los sockets UDP.

2) Llama shutdown() sólo cuando se sienta que es necesario para evitar cualquier código de la realización de un futuro recv y/o send en el zócalo. Normalmente no es necesario, aunque lo he visto utilizado en sockets TCP para obligar al socket a enviar un RST cuando está cerrado (a diferencia del apagado "elegante" predeterminado donde se procesan los envíos pendientes).

3) Puede pensar en sockets como una forma de comunicación de dos canales: uno para leer y el otro para enviar. Puede cerrar uno independientemente del otro y puede continuar utilizando un canal cuando el otro está apagado (es decir, puede seguir recibiendo después de apagar el envío y viceversa). Cerrar un socket es idéntico al apagado de llamadas tanto en recv como en envío.

Apagar por recv simplemente evita que su código lea más datos. Si intenta hacerlo, obtendrá un error de socket. Del mismo modo, si el otro lado de la conexión intenta enviarle datos, recibirá un error (lo siento por cambiar al mundo TCP de nuevo, pero creo que un RST recibe una respuesta al remitente).

Apagar para enviar también evita que su código envíe más datos. Si la memoria me sirve correctamente, esto parece idéntico a lo que sucede cuando cierras un socket (se envía un paquete de longitud cero para indicar al otro lado que el canal en particular se ha cerrado). Cualquier intento futuro de enviar devolverá un error.

4) Deberá verificar sus documentos para asegurarse. MSDN le dará una muy buena indicación, aunque no sé si lo consideraría autoritario.

+0

Gracias, he descubierto algo de esto, pero todavía no estoy seguro de si close() en realidad se llama en destructor de la toma de corriente. Lo que realmente no había grok'ed fue la estrecha conexión entre boost asio y programación de red tradicional. Tanto su explicación de shutdown() como la sugerencia de analizar los códigos de error de socket msdn sugieren esto. +1 – Torleif

+0

Me alegro de poder ayudar :) – Brian

+0

FWIW, llamar .shutdown (BOTH) en un socket UDP funciona para mí en Windows, pero explota en Linux porque el socket no está conectado. –

1

De los ejemplos dados en el sitio web de Boost, parece que debería simplemente usar close().Por ejemplo, un vistazo a éste:

 
void connection::stop() 
{ 
    socket_.close(); 
} 

Tomado de esta dirección: HTTP Server

Cuestiones relacionadas