/ / Zlyhanie deskriptora chybného súboru Boost socket - c ++, boost, boost-asio

Nesprávny deskriptor súborov zatvorený Boost socket - c ++, boost, boost-asio

Používam Boost 1.45 ASIO na zvládnutie niektorých soketových pripojení v aplikácii, ktorá beží na Windows aj Mac. V systéme Windows nasledujúci kód nespôsobuje žiadne chyby a moje zásuvky sú čisto zatvorené. Na počítačoch Mac však vypínanie a (ak to komentujem) funkcie zatvorenia mi dávajú chyby „nesprávneho deskriptora súboru“. Až do doby, keď zavolám tento kód, budú zásuvky fungovať dobre. Ale akonáhle zavolám vypnutie alebo zatvorenie, zobrazí sa chyba. Nejaké nápady, čo by sa mohlo diať?

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

odpovede:

2 pre odpoveď č. 1
if(socket.is_open())
{
socket.shutdown(socket.both);
socket.close();
}

Pokiaľ nemáte na to dobrý dôvod, odporúčam vám socket::~socket() deštruktor zatvorí základný deskriptor natívneho súboru. Ak sa obávate úniku deskriptorov, použite nástroj ako valgrind analyzovať váš program.


7 pre odpoveď č. 2

"Chybný deskriptor súboru" close zvyčajne znamená, že deskriptor už bol uzavretý. Je to často kvôli chybe dvojitého zatvorenia v niektorej úplne nesúvisiacej časti programu.

Takáto chyba môže byť nákazlivá. Ak váš program zatvorí ten istý deskriptor dvakrát, a dočasne sa znova pridelí, druhý close uzavrie deskriptor nesúvisiacich objektovzdola. A potom, keď tento objekt zatvorí svoj deskriptor, môže to byť vlastne zatváranie deskriptora iného objektu ... A tak ďalej, až kým posledný riadok nedostane chybu „nesprávneho deskriptora súboru“.

Toto je vedľajší účinok (a) deskriptorov ako globálneho stavu a (b) požiadavky Unixu, aby každé volanie na otvorenie / soket / atď. priradiť nepoužitý deskriptor s najnižším číslom.

Jediný spôsob, ako viem ladiť, je sledovať vytváranie a ničenie všetkých deskriptorov súborov pomocou nástroja ako strace (v systéme Linux) alebo dtrace (v počítačoch Mac). (Nuž, možno nie jediný spôsob. Raz som napísal potichu LD_PRELOAD hack pre zachytenie každého hovoru open a close aby sme zistili, ktoré vlákno dvojnásobne zatváralo ich deskriptor, pretože druhé zatváranie nukovalo popisovač používaný iným vláknom ...)

Veľa štastia.


0 pre odpoveď č. 3

Mal som rovnaký problém: v systéme Windows bolo všetko v poriadku a v prípade linuxu bola v závislosti od stavu soketu IIRC vyvolaná výnimka.

Alternatívou k Samovej odpovedi je použitie figuríny error_code na tiché ignorovanie výnimky, ak k nej dôjde. Zavrieť a vypnúť preťaženia v dokumentácii ASIO.