繁体   English   中英

坏文件描述符关闭Boost套接字

[英]Bad file descriptor closing Boost socket

我正在使用Boost 1.45 ASIO来处理在Windows和Mac上运行的应用程序中的某些套接字连接。 在Windows上,以下代码不会导致任何错误,我的套接字将完全关闭。 在Mac上,关闭和(如果我注释掉)关闭函数都会给我“错误的文件描述符”错误。 直到我调用此代码,套接字工作正常。 但是一旦我调用shutdown或close,我就会收到错误。 什么想法可能会发生什么?

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

close “错误的文件描述符”通常意味着描述符已经关闭。 这通常是因为程序中某些完全不相关的部分存在双重错误。

这样的错误可能具有传染性。 如果你的程序关闭了相同的描述符两次,并且它在临时中被重新分配,那么第二次close将从它们下面关闭一些不相关的对象的描述符。 然后当该对象关闭其描述符时,它实际上可以关闭另一个对象的描述符......依此类推,直到最后一个对象获得“错误的文件描述符”错误。

这是(a)描述符是全局状态和(b)Unix要求任何对open / socket / etc的调用的副作用。 分配编号最小的未使用描述符。

我知道调试它的唯一方法是使用诸如strace (在Linux上)或dtrace (在Mac上)之类的工具来监视所有文件描述符的创建和销毁。 (好吧,也许不是唯一的方法。我曾经编写了一个复杂的LD_PRELOAD hack来拦截每个调用openclose来找出哪个线程正在双重关闭它们的描述符,因为第二个关闭是对另一个线程使用的描述符进行核对。 ..)

祝好运。

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

除非你有充分的理由这样做,否则我建议让socket::~socket()析构函数关闭底层的本机文件描述符。 如果您担心泄漏描述符,请使用valgrind之类的工具来分析您的程序。

我有同样的问题:在Windows上一切正常,在Linux上,根据套接字状态IIRC抛出异常。

Sam的答案的另一种方法是使用伪error_code在发生异常时静默忽略该异常。 请参阅asio文档中的关闭关闭重载。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM