【问题标题】:socket timeout: It works, but why and how, mainly the select() function?套接字超时:它有效,但为什么以及如何,主要是 select() 函数?
【发布时间】:2011-10-19 10:30:19
【问题描述】:

这是我现在使用的部分代码。

fd_set fdset;
struct timeval tv;
int flags = fcntl(sockfd, F_GETFL);    
fcntl(sockfd, F_SETFL, O_NONBLOCK);

connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr));

FD_ZERO(&fdset);
FD_SET(sockfd, &fdset);
tv.tv_sec = 3;          
tv.tv_usec = 0;

if (select(sockfd + 1, NULL, &fdset, NULL, &tv) == 1)
{
    int so_error;
    socklen_t len = sizeof so_error;
    getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &so_error, &len);
    if (so_error == 0) {
        cout << " - CONNECTION ESTABLISHED\n";
    }
} else
{
    cout << " - TIMEOUT\n";
    exit(-1);
}

我不太清楚 select() 函数是如何工作的,这里的伪代码是我真正想做的,

    bool showOnce = true;

    connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) 
    while(stillConnecting) /*Some kind of flag of connection status*/
    {
        if(showOnce)
        {
            showOnce = false;
            cout << "Connecting";
        }
    }

    if(connected) /*Another possible flag if it exists*/
        return true;
    else
        return false;

有没有办法实现这个伪代码,这些标志存在吗?

编辑:为什么 sockfd+1 在上面代码的选择函数中?为什么要加一个?

【问题讨论】:

  • 阅读select() 的文档时,您学到了什么?
  • 我还没有真正学习,对不起,我主要做嵌入式开发,需要编写一个快速的pc程序来进行简单的通信。在我写这篇评论时,我目前正在阅读关于 select 功能的 msdn 页面。我想我可以用它来检查套接字的状态,就像在伪代码中一样。试图弄清楚如何。我到了:)

标签: c sockets select timeout


【解决方案1】:

阅读手册:man 2 select:

  1. nfds is the highest-numbered file descriptor in any of the three sets, plus 1.,这就是为什么sockfd + 1
  2. select() 返回触发请求事件的描述符数量。只给了一个描述符,所以select最多可以返回1
  3. 因此,如果在给定的超时 3 秒后,没有任何反应,select() 不会返回 1,因此您认为这是超时。不处理错误-1 的情况。

【讨论】:

  • man 3 select 表示“手册第 3 节(库函数)”。您实际上应该阅读第 2 节,系统调用。
  • man man 解释它。它是手册中的部分,以防给定的关键字出现在多个部分中。 - 3 代表库调用(程序库中的函数)
  • 我修正了我的文字。 man 3 select 实际上显示了FD_SET(3) 手册,其中还包含select()。猜猜这就是我得到 3 的地方。
  • 我现在正在阅读有关它的文档,您所说的“只给出了一个描述符,因此 select 最多可以返回 1 个。”您是指上面 select() 调用中的第三个选项吗? select(sockfd + 1, NULL, &fdset, NULL, &tv), &fdset。那么这个函数是否检查套接字是否可写?如果我这样做: select(sockfd + 1, &fdset2, &fdset, NULL, &tv) 是否会检查可写性和可读性,返回可能的值范围从 -1 到 2?这也是我检查我所指的那些“标志”的方法吗?
  • nfdsselect()的第一个参数。如果您没有安装手册,请在线阅读:kernel.org/doc/man-pages/online/pages/man2/select.2.html
猜你喜欢
  • 2020-12-22
  • 1970-01-01
  • 2012-03-20
  • 1970-01-01
  • 2014-06-01
  • 2022-01-22
  • 2016-10-26
  • 2013-02-13
  • 2020-03-13
相关资源
最近更新 更多