我有一个在嵌入式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/