select 与 I/O多路转接

参考博客:http://blog.sina.com.cn/s/blog_607072980102uxcw.html

 

I/0多路转接

描述符表示某个I/O。构造一张有关描述符的数据表,调用select函数,返回准备就绪的描述符,如果没有描述符准备好,则一直阻塞,超时返回0。

 

int select( int maxfdp1, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, sturct timeval *tvptr);
返回:准备就绪的描述符,若超时则为0,若出错则为-1

maxfdp1为最大描述符值,设置为一个常数;

readfds、writefds、exceptfds是指向描述符集的指针,表示我们关心的可读、可写和处异常条件的描述符;

tvptr表示愿意等待的时间(秒、微秒),tvptr=NULL在捕捉到信号前永远等待。

 

描述符集

fd_set rset; //描述符集

int fd; //描述符集的位,表示一个描述符

FD_ZERO(fd_set *fdset); //清空fdset中的所有位

FD_SET(int fd, fd_set *fdset); //在fdset中打开fd所对应的位

FD_CLR(int fd, fd_set *fdset); //在fdset中关闭fd所对应的位

FD_ISSET(int fd, fd_set *fdset); //测试fd是否在fdset中

 

socket单线程并发程序select代码:

int main(int argc,char* argv[])
{
    int ret,n;
    int sockFd;
    struct sockaddr_in servAddr;
    fd_set oset,nset;
    char strBuf[BUFSIZE];
    //UDP地址绑定到服务器
    if(argc!=3)
        errexit("USAGE:%s hostname port",argv[0]);
    sockFd=connectSock(argv[1],argv[2],"udp");
    //初始化fd_set对象
    FD_ZERO(&oset);
    FD_SET(STDIN_FILENO,&oset);
    FD_SET(sockFd,&oset);
    nset=oset;
    while(1)
    {
        ret=select(4,&nset,NULL,NULL,0);
        if(FD_ISSET(sockFd,&nset))
        {
            memset(strBuf,0,BUFSIZE);
            recv(sockFd,strBuf,BUFSIZE,0);
            printf("%s",strBuf);
        }
        if(FD_ISSET(STDIN_FILENO,&nset))
        {
            fgets(strBuf,BUFSIZE,stdin);
            send(sockFd,strBuf,sizeof(strBuf),0);
            memset(strBuf,0,BUFSIZE);
        }
        nset=oset;
    }
}

 

posted @ 2016-05-04 15:59  Expresso  阅读(201)  评论(0编辑  收藏  举报