为什么选择()总是第一个超时后返回0 [英] why select() always return 0 after the first timeout

查看:141
本文介绍了为什么选择()总是第一个超时后返回0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于选择功能问题时,我曾在Linux套接字程序。由于该男子说:页如果客户端连接服务器端的服务器配置的时间间隔的选择功能工作的罚款。如果超时发生,select函数将永远返回0。在那个时候,我调试客户端和找到客户端已连接到服务器。但选择功能仍返回0。我有搜索这个问题,但没有发现任何有用的。可能有人知道为什么选择这样做?我的Linux版本为RHEL5.4。谢谢你的帮助。

在code如下图所示。

 静态const int的maxLog = 10000;诠释的main()
{
    INT servSock;
    信号(SIGPIPE,SIG_IGN);
    如果((servSock =插座(AF_INET,SOCK_STREAM,0))小于0)
    {
        的printf(插座创建失败\\ n);
        出口(-1);
    }
    INT VAL = 1;
    如果(setsockopt的(servSock,SOL_SOCKET,SO_REUSEADDR,和放大器; VAL,sizeof的(VAL))小于0)
    {
        DieWithUserMessage(setsockopt的错误);
    }    结构SOCKADDR_IN serverAddr;
    memset的(安培; serverAddr,0,sizeof的(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serverAddr.sin_port = htons(22000);    如果(绑定(servSock,(结构sockaddr *)及serverAddr,
                的sizeof(serverAddr))≤; 0)
    {
        的printf(套接字绑定失败\\ n);
        出口(-1);
    }    如果(听(servSock,maxLog)℃下)
    {
        输出(听失败\\ n);
        出口(-1);
    }    FD_SET read_set;
    FD_ZERO(安培; read_set);
    FD_SET(servSock,&安培; read_set);
    INT maxfd1 = servSock + 1;
    的std ::集< INT> fd_readset;    对于(;;){
        timeval结构电视;
        tv.tv_sec = 5;
        INT RET =选择(maxfd1,&安培; read_set,NULL,NULL,电视);
        如果(RET == 0)
            继续;        如果(RET℃下)
            DieWithUserMessage(选择错误);        如果(FD_ISSET(servSock,&安培; read_set))
        {
            结构SOCKADDR_IN clntAddr;
            socklen_t的clntAddrlen = sizeof的(clntAddr);
            INT clntSock =接受(servSock,(结构sockaddr *)及clntAddr,&安培; clntAddrlen);
            如果(clntSock℃,)
            {
                输出(接受失败());
                出口(-1);
            }            maxfd1 = 1 +(servSock&GT = clntSock servSock:clntSock);
            FD_SET(clntSock,&安培; read_set);
            fd_readset.insert(clntSock);
         }    }
}


解决方案

的<一个href=\"http://www.opengroup.org/onlinepubs/9699919799/functions/select.html\">'<$c$c>select()'功能是令人沮丧的使用;你必须在每次调用它,因为它会修改之前的时间设置其参数。你们看到的是,如果你不设置了FD_SET(S)周围的循环,每次发生什么的示范。

I have a problem about select function when I worked on a Linux socket program. The select function worked fine as the man page says if the client connected the server side in the time interval configured by the server. If the timeout happened, the select function will return 0 forever. At that time, I debug the client and find the client had connected to the server. But the select function still return 0. I have search this problem but found none helpful. Could someone know why select did like that? My linux version is RHEL5.4. Thank you for your help.

The code is illustrated below.

static const int maxLog = 10000;

int main()
{
    int servSock;
    signal(SIGPIPE, SIG_IGN);
    if((servSock = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
    {
        printf("socket create fail\n");
        exit(-1);   
    }
    int val = 1;
    if(setsockopt(servSock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))<0)
    {
        DieWithUserMessage("setsockopt error");
    }

    struct sockaddr_in serverAddr;
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serverAddr.sin_port = htons(22000);

    if(bind(servSock, (struct sockaddr *) &serverAddr, 
                sizeof(serverAddr)) < 0)
    {
        printf("socket bind  fail\n");
        exit(-1);   
    }

    if(listen(servSock, maxLog) < 0)
    {
        printf("listen failed\n");
        exit(-1);
    }   

    fd_set read_set;
    FD_ZERO(&read_set);
    FD_SET(servSock, &read_set);
    int maxfd1 = servSock + 1; 
    std::set<int> fd_readset;

    for(;;){    
        struct timeval tv;
        tv.tv_sec = 5;
        int ret = select(maxfd1, &read_set, NULL, NULL, tv);       
        if(ret == 0)
            continue;

        if(ret < 0)
            DieWithUserMessage("select error");

        if(FD_ISSET(servSock, &read_set))
        {
            struct sockaddr_in clntAddr;
            socklen_t clntAddrlen = sizeof(clntAddr);
            int clntSock = accept(servSock, (struct sockaddr *) &clntAddr, &clntAddrlen);
            if(clntSock < 0)
            {
                printf("accept failed()");
                exit(-1);
            }   

            maxfd1 = 1 +  (servSock>=clntSock? servSock:clntSock);
            FD_SET(clntSock, &read_set );
            fd_readset.insert(clntSock); 
         }

    } 
}

解决方案

The 'select()' function is frustrating to use; you have to set up its arguments each time before you call it because it modifies them. What you are seeing is a demonstration of what happens if you don't set up the fd_set(s) each time around the loop.

这篇关于为什么选择()总是第一个超时后返回0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆