/ / Descriptor de archivo incorrecto que cierra el socket Boost - c ++, boost, boost-asio

Descriptor de archivo defectuoso al cerrar el socket Boost - c ++, boost, boost-asio

Estoy usando Boost 1.45 ASIO para manejar algunas conexiones de socket en una aplicación que se ejecuta tanto en Windows como en Mac. En Windows, el siguiente código no causa ningún error y mis enchufes se cierran limpiamente. Sin embargo, en Mac, tanto el apagado como (si lo comento) las funciones de cierre me dan errores de "descriptor de archivo incorrecto". Hasta que llame a este código, los enchufes funcionan bien. Pero tan pronto como llamo a shutdown o close, recibo el error. ¿Alguna idea de lo que podría estar pasando?

if(socket.is_open())
{
socket.shutdown(socket.both);
socket.close();
}

Respuestas

2 para la respuesta № 1
if(socket.is_open())
{
socket.shutdown(socket.both);
socket.close();
}

A menos que tenga una buena razón para hacer esto, sugiero dejar que socket::~socket() destructor cierra el descriptor de archivo nativo subyacente. Si le preocupan los descriptores de fugas, use una herramienta como valgrind para analizar su programa.


7 para la respuesta № 2

"Descriptor de archivo mal" en close Usualmente significa que el descriptor ya ha sido cerrado. Esto se debe a menudo a un error de doble cierre en alguna sección del programa que no está relacionada por completo.

Tal error puede ser contagioso. Si su programa cierra el mismo descriptor dos veces y se vuelve a asignar en el ínterin, el segundo close cerrará el descriptor de algún objeto no relacionadode debajo de ellos. Y luego, cuando ese objeto cierra su descriptor, en realidad puede estar cerrando otro descriptor de otro objeto ... Y así sucesivamente, hasta que el último en la línea reciba un error de "descriptor de archivo incorrecto".

Este es un efecto secundario de (a) que los descriptores son estado global y (b) el requisito de Unix de que cualquier llamada a open / socket / etc. Asigne el descriptor no utilizado con el número más bajo.

La única forma que conozco de depurar esto es monitorear la creación y destrucción de todos los descriptores de archivos usando una herramienta como strace (en Linux) o dtrace (en Mac). (Bueno, tal vez no sea la única manera. Una vez escribí un retorcido LD_PRELOAD hackear para interceptar cada llamada a open y close para averiguar qué subproceso cerró dos veces su descriptor, porque el segundo cierre fue oprimir el descriptor que está utilizando otro subproceso ...)

Buena suerte.


0 para la respuesta № 3

Tuve el mismo problema: en Windows todo estaba bien, y en Linux, se lanzó una excepción según el estado del socket IIRC.

Una alternativa a la respuesta de Sam es usar un código de error ficticio para ignorar silenciosamente la excepción si ocurre. Vea la cerca y apagar Sobrecargas en la documentación de asio.