C-如何在UDP中使用Linux中的选择API


 int CreateSocket()
 {
     socklen_t len;
   // Socket creation for UDP
   acceptSocket=socket(AF_INET,SOCK_DGRAM,0);
   if(acceptSocket==-1)
   {
     printf("Failure: socket creation is failed, failure coden");
     return 1;
   }
   else
   {
     printf("Socket started!n");
   }
 memset(&addr, 0, sizeof(addr));
 addr.sin_family=AF_INET;
 addr.sin_port=htons(port);
 addr.sin_addr.s_addr=htonl(INADDR_ANY);
 rc=bind(acceptSocket,(struct sockaddr*)&addr,sizeof(addr));
 if(rc== -1)
 {
     printf("Oh dear, something went wrong with bind()! %sn", strerror(errno));
   return 1;
 }
 else
 {
   printf("Socket an port %d n",port);
 }
   while(rc!=-1)
   {
       fd_set master;
       fd_set read_fds;
       int retval;
       FD_ZERO(&master);
       FD_ZERO(&read_fds);
       FD_SET(acceptSocket, &master);
       FD_SET(acceptSocket, &read_fds);
       retval =select(2, &master, NULL, NULL, NULL);
       len = sizeof(client);
       if(retval == -1)
       {
           printf("errorn");
       }
       else if(FD_ISSET (acceptSocket, &master))
       {
     rc=recvfrom(acceptSocket,buf, 256, 0, (struct sockaddr*) &client, &len);
     if(rc==0)
     {
       printf("Server has no connection..n");
       break;
     }
     if(rc==-1)
     {
         printf("Oh dear, something went wrong with read()! %sn", strerror(errno));
       break;
     }
     XcpIp_RxCallback( (uint16) rc, (uint8*) buf, (uint16) port );
       }
       else
       {
           makeTimer("First Timer", &firstTimerID, 2, 2);   //2ms
                             makeTimer("Second Timer", &secondTimerID, 10, 10);    //10ms
                             makeTimer("Third Timer", &thirdTimerID, 100, 100);  //100ms
       }

   }

   close(acceptSocket);

   return 0;
   }

以上是UDP层的服务器代码,可通过IP地址和端口号从客户端收拾数据。我正在使用SELECT API检查是否通过端口进行数据,然后收回数据,否则调用计时器fucntion。我想实现从客户那里收取数据,并在收到后,我必须致电计时器。但是上面的代码没有调用计时器任务。上述代码中的错误是什么?使用选择API ??

是否有效

select()的第一个参数是1 最高fd-in-in-the-in-the-in-the-in-three-sets,因此应接受 1。

(我假设您的实际问题比上述代码更为复杂,因为您可以进行blocking recvfrom()调用,而不是select()。单个线程中的插座和/或超时后唤醒封锁调用 - 尽管有其他方法可以做后者。)

使用 timeout == null调用 select()的方式,它将阻止它,直到 master中的文件描述中有一个数据。在您的情况下,只有master仅包含 acceptSocket,您将无法到达makeTimer()else

struct timeval timeout;
timeout.tv_sec = 0l;
timeout.tv_usec = 0l; 
retval = select( acceptSocket+1, master, NULL, NULL, &timeout );

只是在不阻止的情况下检查

请注意,select()由于超时而返回0,并且返回描述符集中包含的文件描述符数量否则。因此,您还必须更改状况:

else if(FD_ISSET (acceptSocket, &master))

to

else if(retval > 0 && FD_ISSET (acceptSocket, &master))

因为否则您也将在Timout之后致电recvfrom(),在这种情况下,它将阻止

最新更新