本文介绍了使用 select 系统调用阻止 recvfrom的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 UDP 客户端,它必须从两个不同的套接字接收.
我正在使用 select 系统调用来复用 recv 调用.

I have a UDP client which has to receive form two different sockets.
I am using select system call to multiplex the recv call.

但我看到客户端在第二个 recv 调用中被阻塞.

But I am seeing that the client is blocked inside the second recv call.

我该如何解决这个问题?

How can I resolve this issue?

struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
int activity;

FD_ZERO(&socketfds);
FD_SET(usocket,&socketfds);
max_sd = std::max(max_sd, usocket);
FD_SET(msocket,&socketfds);
max_sd = std::max(max_sd, msocket);
rset = socketfds;

do
{
      rset = socketfds;
      activity = select( max_sd + 1 , &rset , NULL , NULL , &timeout);
}
while(activity<0 && errno == EINTR);

if ((activity < 0) && (errno!=EINTR))
{
     printf("select error");
}
if(FD_ISSET(usocket, &socketfds))
{
      int len;
      printf("Receiving from unicast socket..\n");
      if((len = recvfrom(usocket, dataBuffer, dataLength, 0, (struct sockaddr *)
   &clientAddr, &clen) < 0) )
     {
           printf("Error reading message \n");
           close(msocket);
           exit(-1);
     }
     else
     {
             printf("Size of message: %d\n", strlen(dataBuffer));
             handleMessage(dataBuffer);
     }
}
if(FD_ISSET(msocket, &socketfds))
{
     printf("Receiving from multicast socket..\n");
     if((recvfrom(msocket, dataBuffer, dataLength, 0, (struct sockaddr *)
   &multicastClientAddr, &mlen) < 0) )
    {
       printf("Error reading message \n");
       close(msocket);
       exit(-1);
    }
    else
    {
      printf("Message from server:%s\n", dataBuffer);
      handleMessage(dataBuffer);
    }
}

推荐答案

您需要检查 select 返回(修改)的 rset 以查看套接字是否已准备好读取 - 这些位将始终在 socketfds 中设置,因为这是您要等待的主要套接字集.所以改变

You need to check the rset returned (modified) by select to see if the sockets are ready to read -- the bits will ALWAYS be set in socketfds since that is your master set of sockets to wait for. So change the

if(FD_ISSET(Xsocket, &socketfds))

行到

if(FD_ISSET(Xsocket, &rset))

这篇关于使用 select 系统调用阻止 recvfrom的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 21:38