我正在使用Boost 1.45 ASIO来处理在Windows和Mac上运行的应用程序中的某些套接字连接。在Windows上,以下代码不会导致任何错误,我的套接字将完全关闭。在Mac上,关闭和(如果我注释掉)关闭函数都会给我“错误的文件描述符”错误。直到我调用此代码,套接字工作正常。但是一旦我调用shutdown或close,我就会收到错误。可能会发生什么想法?
if(socket.is_open())
{
socket.shutdown(socket.both);
socket.close();
}
答案 0 :(得分:7)
close
上的“错误文件描述符”通常意味着描述符已经关闭。这通常是因为程序中某些完全不相关的部分存在双重错误。
这样的错误可能具有传染性。如果你的程序关闭了两次相同的描述符,并且它在过渡期间被重新分配,那么第二个close
将从它们下面关闭一些不相关的对象的描述符。然后当该对象关闭其描述符时,它实际上可以关闭另一个对象的描述符......依此类推,直到最后一个对象获得“错误的文件描述符”错误。
这是(a)描述符是全局状态的副作用,以及(b)对open / socket / etc的任何调用的Unix要求。分配编号最小的未使用描述符。
我知道调试它的唯一方法是使用strace
(在Linux上)或dtrace
(在Mac上)等工具监视所有文件描述符的创建和销毁。 (好吧,也许不是唯一的方法。我曾经写过一个复杂的LD_PRELOAD
黑客来拦截对open
和close
的每次调用,以找出哪个线程正在双重关闭它们的描述符,因为第二次关闭是另一个线程使用的描述符......)
答案 1 :(得分:2)
if(socket.is_open())
{
socket.shutdown(socket.both);
socket.close();
}
除非你有充分的理由这样做,否则我建议让socket::~socket()
析构函数关闭底层的本机文件描述符。如果您担心泄漏描述符,请使用valgrind之类的工具来分析您的程序。
答案 2 :(得分:0)