我有一个在嵌入式Linux(旧版内核,2.6.18)上运行的应用程序。我正在使用Live555。有时,当摄像机负载很重时,我的RTSP服务器(使用Live555构建)将无限期挂起-似乎没有多少连接或耦合可以使它脱颖而出,而无需重置应用程序。

我将范围缩小到以下代码:

static int blockUntilReadable(UsageEnvironment& env,
                  int socket, struct timeval* timeout) {
  int result = -1;
  do {
    fd_set rd_set;
    FD_ZERO(&rd_set);
    if (socket < 0) break;
    FD_SET((unsigned) socket, &rd_set);
    const unsigned numFds = socket+1;

    result = select(numFds, &rd_set, NULL, NULL, timeout);  <--HANG

当然,超时是一个NULL指针,它指示它应该阻塞直到其中一个套接字可读为止。问题是:是否连接到RTSP服务器并不重要-它只是无限期地阻塞。

我做了一个netstat -an,它总是输出类似:
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 0.0.0.0:5222            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:5800            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:5802            0.0.0.0:*               LISTEN
tcp       21      0 0.0.0.0:554             0.0.0.0:*               LISTEN

当它处于故障状态时,我总是在Recv-Q上看到21,这是“连接到此套接字的用户程序未复制的字节数”。

有谁知道会发生什么事,或者我如何解决此问题?

最佳答案

该代码看起来很扎实。对于您为什么要转换为unsigned int,我有点好奇,但是它不会对您造成任何伤害。

一些想法:

它并没有悬卡在您认为的位置。希望您已经对此进行了两次/三次检查。 (再次检查?)

您的netstat解释错误。如手册页所述,该部分用于“已建立”的套接字-您的是侦听器,它是下一个句子:“侦听:自内核2.6.18起,此列包含当前的syn backlog。”

这似乎是一个巨大的积压。。。这使我觉得您没有被accept()接收,也许是因为您被卡在select()中。那就是您的监听套接字上的select()对吗?

最后,仔细检查您要在右侧套接字上调用select()的。即,打印出该套接字arg,看看它是否应该是它。

本质上,请验证:1)它卡在select()中,并且2)要选择的参数正确。我怀疑这两个都不正确。

关于c++ - select()无限期挂起,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2978488/

10-17 00:21