socket select模型(一)

来源:互联网 发布:聚合数据api 编辑:程序博客网 时间:2024/06/06 03:49

fd_set编辑

select()机制中提供一fd_set的数据结构,实际上是一long类型的数组,每一个数组元素都能与一打开的文件句柄(不管是socket句柄,还是其他文件或命名管道或设备句柄)建立联系,建立联系的工作由程序员完成,当调用select()时,由内核根据IO状态修改fd_set的内容,由此来通知执行了select()的进程哪一socket或文件发生了可读或可写事件。


fd_set set;
FD_ZERO(&set); /*将set清零使集合中不含任何fd*/
FD_SET(fd, &set); /*将fd加入set集合*/
FD_CLR(fd, &set); /*将fd从set集合中清除*/
FD_ISSET(fd, &set); /*在调用select()函数后,用FD_ISSET来检测fd在fdset集合中的状态是否变化返回整型,当检测到fd状态发生变化时返回真,否则,返回假(0)*/
以上式子中的fd为socket句柄。
#include <stdio.h>#include <sys/select.h>#include <unistd.h>int main(int argc, char **argv){        fd_set fdset;        FD_ZERO (&fdset);                          /*清空集合中所有的元素*/        FD_SET(STDOUT_FILENO,&fdset);              /*设置stdout,使集合中包含stdout*/             if(FD_ISSET(STDOUT_FILENO,&fdset)!=0)      /*测试stdout是否包含在集合中*/                printf("stdout has been set\n");        else                printf("stdout has not been set\n");                FD_CLR(STDOUT_FILENO,&fdset);              /*从位向量中清除stdout*/             if(FD_ISSET(STDOUT_FILENO,&fdset)!=0)      /*再次测试*/               printf("stdout has been set\n");        else                printf("stdout has not been set\n");        return 0;}

从网络上接受数据写入一个文件中。 main() {     int sock;     FILE *fp;     struct fd_set fds;     struct timeval timeout={3,0}; //select等待3秒,3秒轮询,要非阻塞就置0     char buffer[256]={0}; //256字节的接收缓冲区     /* 假定已经建立UDP连接,具体过程不写,简单,当然TCP也同理,主机ip和port都已经给定,要写的文件已经打开     sock=socket(...);     bind(...);     fp=fopen(...); */     while(1)    {         FD_ZERO(&fds); //每次循环都要清空集合,否则不能检测描述符变化         FD_SET(sock,&fds); //添加描述符         FD_SET(fp,&fds); //同上         maxfdp=sock>fp?sock+1:fp+1;    //描述符最大值加1         switch(select(maxfdp,&fds,&fds,NULL,&timeout))   //select使用         {             case -1: exit(-1);break; //select错误,退出程序             case 0:break; //再次轮询             default:                   if(FD_ISSET(sock,&fds)) //测试sock是否可读,即是否网络上有数据                   {                         recvfrom(sock,buffer,256,.....);//接受网络数据                         if(FD_ISSET(fp,&fds)) //测试文件是否可写                             fwrite(fp,buffer...);//写入文件                          buffer清空;                    }// end if break;           }// end switch      }//end while }//end main 



0 0
原创粉丝点击