select 与 I/O多路转接

徘徊边缘 提交于 2019-12-23 06:43:44

参考博客: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;
    }
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!