【问题标题】:select for timeout over TCP socket选择通过 TCP 套接字超时
【发布时间】:2013-06-08 21:50:32
【问题描述】:

我对这段代码有疑问:

FD_ZERO(&cset);
FD_SET(s, &cset);

tval.tv_sec = TIMEOUT; 
tval.tv_usec = 0; 

n = select(FD_SETSIZE, &cset, NULL, NULL, &tval);

if (n==-1) {
    printf(" select() failed \n");
    exit(-1);
}
if (n>0) {
    check_control = connect(s,(struct sockaddr*)
    &indirizzo_remoto,sizeof(indirizzo_remoto));

    if (check_control == -1) {
        printf("Errore connect()\n");
    }

}else{
    printf("Timeout. I'll shutdown the client");
    exit(-1);
}

我想为连接插入超时,但它不起作用:

我使用了正确的服务器 IP 地址和端口号,但连接超时。

非常感谢您的帮助。

【问题讨论】:

  • 是的,使用 telnet 就可以了!
  • 这是错的吗?因为我想要的是当客户端尝试与它连接时服务器已关闭,如果客户端停止并关闭套接字需要 30 秒
  • (对不起英文)......:如果服务器/客户端尝试连接到它,我想要那个
  • select() 不会为您连接()套接字。如果您想使用超时进行连接(),您需要 1. 将套接字设置为非阻塞模式。 2. 调用 connect() 3. 调用 select()。您是否完成了第 1 步和第 2 步?我们只看到第 3 步的代码。
  • 我以为只有这一段代码实现了想要的结果。如何完成第 1 步和第 2 步?

标签: sockets select timeout connect


【解决方案1】:

在调用connect() 之前,您正在使用select() 检查给定的套接字是否处于可读 状态。那永远行不通。未连接的 TCP 套接字永远不会处于可读状态,并且在首先调用 connect() 之前不能与 select() 一起使用。

实现connect() 调用超时的唯一方法是首先将套接字置于非阻塞模式(默认情况下,套接字是阻塞的),然后调用connect()(如果socket正在尝试连接),然后使用select()等待socket进入可写状态,表示连接成功,或者错误状态,表示连接失败。

试试这个:

fcntl(s, F_SETFL, O_NONBLOCK);

或者:

flags = 1;
ioctl(s, FIOBIO, &flags);

取决于您的平台。

然后:

check_control = connect(s, (struct sockaddr*) &indirizzo_remoto, sizeof(indirizzo_remoto));
if (check_control == -1)
{
    if (errno != EINPROGRESS)
    {
        printf("Errore connect()\n");
        exit(-1);
    }

    FD_ZERO(&wset);
    FD_SET(s, &wset);

    FD_ZERO(&eset);
    FD_SET(s, &eset);

    tval.tv_sec = TIMEOUT; 
    tval.tv_usec = 0; 

    n = select(s+1, NULL, &wset, &eset, &tval);
    if (n == -1)
    {
        printf(" select() failed \n");
        exit(-1);
    }

    if (n == 0)
    {
        printf("Timeout. I'll shutdown the client");
        exit(-1);
    }

    if (FD_ISSET(s, &eset))
    {
        printf("Cannot connect. I'll shutdown the client");
        exit(-1);
    }

    int err = -1;
    getsockopt(s, SOL_SOCKET, SO_ERROR, &err, sizeof(err));
    if (err != 0)
    {
        printf("Cannot connect. I'll shutdown the client");
        exit(-1);
    }
}

// connected...

【讨论】:

  • 现在可以了。感谢您指出(明显的)问题!
猜你喜欢
  • 2019-07-11
  • 2012-11-25
  • 2016-02-09
  • 2013-05-15
  • 2014-05-18
  • 1970-01-01
  • 2012-04-08
  • 2010-12-14
  • 1970-01-01
相关资源
最近更新 更多