最近用select函数接收多个socket的消息
发现了一些奇怪的现象
while(g_Multicast_test.bRunFlag)//死循环
{
TimeoutVal.tv_sec = 0;
TimeoutVal.tv_usec = 1000 * 50;
//select函数会遍历从readfs中的标记s32Maxfd位为起始位置遍历出文件描述符fd,一旦监听到某个端口的数据就会停止阻塞,继续向下执行
if(IsTimeout)
{
i ++;
if(i == MAX_Multicast_Num)
{
i = 0;
//MULT_PRINTF("cyj 1372\n");
readfds = g_Multicast_test.fds;
s32Maxfd = g_Multicast_test.maxfds;
}
s32Ret = select(s32Maxfd+1, &readfds,NULL,NULL, &TimeoutVal);
}
else
{
s32Ret = select(s32Maxfd+1, &readfds,NULL,NULL, NULL);
}
if(s32Ret < 0)
{
MULT_PRINTF("audio recv select() fail !\n");
//usleep(1000 * 10);
continue;
}
else if(s32Ret == 0)
{
//MULT_PRINTF("cyj 1389\n");
if(g_Multicast_test.state == MUL_PLAY)
{
MULT_PRINTF("wait time out,continue next wait \n");
stop_multicast_play(now_play_index);
}
}
else if(FD_ISSET(g_Multicast_test.broadcast_fd[i], &readfds))//FD_ISSET(g_Multicast_test.broadcast_fd[i], &readfds)有消息接收,不代表FD_ISSET(g_Multicast_test.broadcast_fd[now_play_index]有消息接收
{
//MULT_PRINTF("1400\n");//原先用这个打印,发现代码运行的逻辑正常了,因为打印产生了延时的效果
usleep(10000);//延时等待(FD_ISSET(g_Multicast_test.broadcast_fd[0-MAX_Multicast_Num], &readfds)所有的套接字状态刷新
int recvlen = 0;
memset(strRecvBuf,0,sizeof(strRecvBuf));
recvlen = recvfrom(g_Multicast_test.broadcast_fd[i], strRecvBuf, sizeof(strRecvBuf),0, NULL, 0);//返回接受的数据字节
if(recvlen <= 0)
{
usleep(1000);
continue;
}
//MULT_PRINTF("recvlen %d ok",recvlen);
//收到数据包后下面进行刷选,符合条件的才能才能进行解码发送到语音设备播放
if(filter_rule(i))
{
if(!(FD_ISSET(g_Multicast_test.broadcast_fd[now_play_index], &readfds)))//延时相当于让now_play_index对应的套接字状态值刷新,原先没有延时,没有正确判断g_Multicast_test.broadcast_fd[now_play_index]套接字的状态,导致误判,运行逻辑
出现异常
{
now_play_index = i;
}
continue;//丢弃这次收到的数据包
}
sip_multicast_sub_rtphead(strRecvBuf,recvlen);
}
//usleep(1000);
}
如图中代码所示usleep 10000 us 延时使得select函数有时间更新readfds集合中套接字状态值,原先使用的是MUL_PRINTF打印函数,歪打正着产生延时效果,后干脆使用usleep延时函数果然可以,也就是说selcect监听套接字集合,并不是同时产生检测到它们的状态变化,A套接字有消息,还要过一段时间才能检测到B套接字是否有消息,延时一会,才能用FD_ISSET(g_Multicast_test.broadcast_fd[i], &readfds)准确判断该套接字的状态。