Unix / C问题在这里。
我有多个套接字,我正在尝试轮询定期数据。我不希望select无限期地等待,所以我有一个超时,我正在循环运行。我发现一旦插座准备好阅读,就可以随时阅读了。因为,当没有任何数据要从任何套接字读取时,我无法选择进入休眠状态。
for (i = 0; i < n_connections; i++) {
FD_SET( sockfd[i], &master );
if (sockfd[i] > fdmax)
fdmax = sockfd[i];
}
for(;;) {
int nready = 0;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
read_fds = master;
if ( (nready = select(fdmax+1, &read_fds, NULL, NULL, NULL)) == -1 ) {
fprintf( stderr, "Select Error\n" );
return FAILURE;
}
printf( "Number of ready descriptors: %d\n", nready );
for (i = 0; i <= fdmax; i++) {
if (FD_ISSET(i, &read_fds)) {
if (( nbytes = recv(i, buf, sizeof(buf), 0)) <= 0 ) {
if (nbytes == 0) {
//connection closed
printf("Socket %d hung up\n", i );
}
else {
fprintf( stderr, "Recv Error %d\n", nbytes);
}
}
else {
printf( "Data Received on %d: %s\n", i, buf );
}
}
} // end file descriptor loop
似乎在我第一次读取之后,1秒超时不再适用,并且套接字始终“准备好读取”,即使有0个字节可用。如何在数据进入之前选择进入休眠状态(一秒钟,或者将最终参数切换为NULL,无限期地等待数据进入套接字?)
输出:
Number of Ready Descriptors: 2
Data Received on 4: GreetingsChap
Data Received on 5: HiMatengsChap
Loop...
Number of Ready Descriptors: 2
Socket 4 hung up
Socket 5 hung up
Loop...
Number of Ready Descriptors: 2
Socket 4 hung up
Socket 5 hung up
Loop...
谢谢,
注意:为了清晰起见,代码已更新 根据@yvesBraumes建议更新 - 仍然无效。
答案 0 :(得分:6)
如果您检测到连接已关闭,请从fd集中删除套接字,否则select
将报告它们(Socket 4 hung up
)..如果您不是,则选择不是边缘触发处理事件,它将再次报告。
答案 1 :(得分:4)
实际上,如果recv返回0(而不是-1,并且errno = EWOULDBLOCK),则套接字将关闭。您也应该在其上拨打close()
,然后将其从select()
电话中取出。否则它将保持在WAIT1并每次释放select()
。
答案 2 :(得分:0)
您正在错误地使用FD_ISSET。您需要将套接字ID传递给“fd”参数,而不是索引:
<to uri="exec:/somepath/script.sh?args=/startpath/ 30" />
需要
if (FD_ISSET(i, &read_fds))...
与if (FD_ISSET(sockfd[i], &read_fds))...
相同。