C ++选择函数过早中断

时间:2014-11-27 07:40:32

标签: c++ sockets

好的,首先关闭:对不起,如果之前已经询问过这个问题,但是我无法找到正确的关键字。

情况:我有一个小型网络服务器,它运行在自己的线程中。 ' Run' -Method迭代一组活动套接字(UDP和TCP),检查Activity并做它的事情。所有这些都是通过select实现的。

有可能,虽然“卡住了”。在select中添加了一个新服务器。为此,我加入了一个“断路器插座”,与其他插座一起进行检查。添加新套接字时会关闭它,因此还会监视新套接字的流量。 (每次选择被破坏时都会重新生成fd_set)

代码就像这样(缩写):

fd_set fds;
SOCKET mSock = Breaker;

FD_ZERO(&fds);
//Aquire Mutex
if(Breaker == INVALID_SOCKET)
    mSock = Breaker = socket(AF_INET, SOCK_STREAM, 0);
FD_SET(Breaker, &fds);
//Iterate over active sockets and add them to fds.
//Release Mutex

if(select(mSock + 1, &fds, NULL, NULL, NULL) > 0) {
    //AquireMutex
    //Iterate over active sockets, check for activity and act accordingly.
    if(Breaker != INVALID_SOCKET && FD_ISSET(Breaker, &fds)
        //Close Breaker and set it to INVALID_SOCKET
    //Release Mutex
}

现在实际问题是:select不断被打破,无论我是否关闭Breaker。它不断报告'活动'在插座上。

Breaker是一个简单的套接字,没有绑定或连接。 如果我将Breaker的类型更改为' DGRAM',即使关闭,它也不会中断选择。

语言是C ++,Platform是Linux派生的,INVALID_SOCKET定义为-1,SOCKET是int的typedef。 (代码也适用于WinSock)

感谢您的帮助。

编辑: 我试过从缓冲区读取。在断路器套接字上调用recv返回-1,将errno设置为107(传输端点未连接),这并不奇怪,看看它是如何连接的。

编辑: 由于我的意图显然不清楚,我将再次描述它。 有可能在任何给定的时间点将新的服务器套接字添加到队列中。但是,除非select被破坏(并且fd_set随后用新套接字重新填充)至少一次,否则不会监视此套接字的流量。因此丢弃到达新套接字的任何流量。

我知道,我可以使用超时,但我希望它能成为一种不同的解决方案。

2 个答案:

答案 0 :(得分:7)

这是预期的。如果没有什么可以等待的,select就等不及了。如果套接字关闭,则没有什么可以等待的。如果未连接套接字,则无需等待。如果你想让select等待,你必须给它一些等待的东西。当它告诉你没有什么可以等待时,你不应该让它再等一下 - 这没有任何意义。在你再次打电话之前,你必须处理select告诉你的任何事情,否则同样的事情会继续发生。

答案 1 :(得分:2)

您可以使用管道(man 2 pipe)代替使用套接字来发出事件信号。

如果可能的话,我宁愿修改你的架构。

PS:我发誓我没有看过Michael Burr在评论中提出的问题。