套接字超时:它可以工作,但是为什么以及如何工作,主要是 select() 函数?

发布于 2024-11-28 01:19:51 字数 1213 浏览 0 评论 0原文

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

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;

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

编辑:另外为什么上面代码中的 select 函数中是 sockfd+1 ?为什么要加一个呢?

Here is part of the code I'm using now.

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);
}

I don't clearly understand how the select() function works, here in pseudo code is what I really want to do,

    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;

Is there anyway to implement this pseudo code, do these flags exist?

EDIT: Also why is sockfd+1 in the select function in the code above? Why is one added to it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

萌化 2024-12-05 01:19:51

阅读手册:man 2 select

  1. nfds 是三组中编号最大的文件描述符,再加上 1。,这就是为什么 sockfd + 1< /代码>。
  2. select() 返回触发请求事件的描述符数量。仅给出一个描述符,因此 select 最多可以返回 1
  3. 因此,如果在给定的超时时间 3 秒后,没有任何反应,select() 不会返回 1,因此您将其视为超时。错误 -1 的情况不会被处理。

Read the manual: man 2 select:

  1. nfds is the highest-numbered file descriptor in any of the three sets, plus 1., that's why sockfd + 1.
  2. select() returns the number of descriptors which trigger a requested event. Only one descriptor is given, so select can return at most 1.
  3. So if after 3 seconds, the given timeout, nothing happens, select() does not return 1, so you consider it a timeout. The case of an error -1 is not handled.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文