select

#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int
main(void) {
     fd_set rfds;
     struct timeval tv;
     int retval;

     /* Watch stdin (fd 0) to see when it has input. */
     FD_ZERO(&rfds);//// 如果不初始化,会导致不可预期的后果
     FD_SET(0, &rfds);//打开描叙符第0位

     /* Wait up to five seconds. */
     tv.tv_sec = 5;
     tv.tv_usec = 0;
//  原型
//    int select (int maxfdp1,fd_set *readset,fd_set *writeset,   fd_set *exceptset,const struct timeval * timeout);
//  参数
//   参数一:为了保持与早期的Berkeley套接字应用程序兼容,一般忽略它,置为0.   

 参数二:用于检查可读性,   参数三:用于检查可写性,  

 参数四:用于检查带外数据,  

 参数五:一个指向timeval结构的指针,用于决定select等待I/o的最长时间。如果为空将一直等待。

timeval结构的定义:struct timeval{  

 long tv_sec; // seconds   

long tv_usec; // microseconds  

 }

     retval = select(1, &rfds, NULL, NULL, &tv);
     /* Don鈥檛 rely on the value of tv now! */

     if (retval == -1)
         perror("select()");
      else if (retval)
         printf("Data is available now.\n");
   /* FD_ISSET(0, &rfds) will be true. */
     else
         printf("No data within five seconds.\n");

     return 0;
 }

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netdb.h>

int main(int argc,char *argv[])
{
 int srv_sock;
 socklen_t clt_len;
 struct sockaddr_in srv_addr;
 struct sockaddr_in clt_addr;
 struct timeval wait_time;
 int port;
 int ret;
 fd_set read_fds;
 int num; 
 char recv_buf[1024];

 if(argc!=2){
  printf("Usage: %s port_name\n",argv[0]);
  return 1;
 }
 
 port=atoi(argv[1]);

 srv_sock=socket(PF_INET,SOCK_DGRAM,0);
 if(srv_sock<0){
  perror("cannot create socket");
  return 1;
 }

 memset(&srv_addr,0,sizeof(srv_addr));
 srv_addr.sin_family=AF_INET;
 srv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
 srv_addr.sin_port=htons(port);

 ret=bind(srv_sock,(struct sockaddr*)&srv_addr,sizeof(srv_addr));
 if(ret<0){
  perror("cannot bind the socket");
  return 1;
 }

 while(1){
  wait_time.tv_sec=3;
  wait_time.tv_usec=0;
  FD_ZERO(&read_fds);
  FD_SET(srv_sock,&read_fds);
  //使用select函数避免陷入阻塞状态示例
  num=select(srv_sock+1,&read_fds,NULL,NULL,&wait_time);
  if(num<0){
   perror("select fail");
   continue;
  }
  
  if(FD_ISSET(srv_sock,&read_fds)){
   int n=recvfrom(srv_sock,recv_buf,sizeof(recv_buf),0,(struct sockaddr*)&clt_addr,&clt_len);
   if(n<0){
    perror("cannot receive client message");
    close(srv_sock);
    return 1;
   }

   printf("server receive: %s\n",recv_buf);
   memset(recv_buf,0,sizeof(recv_buf));
  }
  printf("waiting....\n");
 }
}

你可能感兴趣的:(select)