在unix域套接字上设置connect()超时

问题描述 投票:0回答:1

使用alarm()是唯一在unix域套接字上设置connect()超时的吗?我已经尝试了select(),它描述了here,但似乎select()每次都在unix域套接字上立即返回ok并且通过调用getsockopt(SO_ERROR)没有发生错误,但是fd上的send()返回错误说Transport endpoint is not connected 。我粘贴下面的select()代码。

我认为使用闹钟会遇到这种情况,但似乎它被认为是一种古老的方式。所以我在这里看看是否还有其他解决方案。提前致谢。

if ((flags = fcntl(fd, F_GETFL, 0)) == -1) {
    syslog(LOG_USER|LOG_ERR, "fcntl get failed: %s", strerror(errno));
    close(fd);
    return -1;
}
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
    syslog(LOG_USER|LOG_ERR, "set fd nonblocking failed: %s", strerror(errno));
    close(fd);
    return -1;
}
if(connect(fd, (struct sockaddr *) &address, sizeof(struct sockaddr_un)) != 0) {
    if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINPROGRESS) {
        close(fd);
        return -1;
    }
    FD_ZERO(&set);
    FD_SET(fd, &set);
    if(select(fd + 1, NULL, &set, NULL, &timeout) <= 0) {
        close(fd);
        return -1;
    }
    /*
    if(connect(fd, (struct sockaddr *) &address, sizeof(struct sockaddr_un)) != 0) {
        close(fd);
        return -1;
    }
    */
    if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len) < 0) {
        syslog(LOG_USER|LOG_ERR, "getsockopt failed: %s", strerror(errno));
        close(fd);
        return -1;
    }
    if(error != 0) {
        syslog(LOG_USER|LOG_ERR, "getsockopt return error: %d", error);
        close(fd);
        return -1;
    }
}
if (fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) == -1) {
    syslog(LOG_USER|LOG_ERR, "set fd blocking failed: %s", strerror(errno));
    close(fd);
    return -1;
}
c sockets timeout
1个回答
0
投票

在另一篇文章的某处(我没有将该页面加入书签)我发现connect()只建立了一个TCP连接。它只意味着在另一端,有一个工作的TCP堆栈,但这并不意味着,服务器实际上有accept()-ed!

connect()的例子就像打电话给支持中心,自动语音告诉你,你在排队,但你还是无法沟通。 accept()是接听电话的实际运营商。

我对同一问题的解决方案是让客户端等待服务器实际发送一些内容,然后继续使用其他客户端内容。我可以把它放在select-timeout循环中。

listen()有一个参数,在开始删除客户端连接尝试之前,可以在待办事项中放入多少个连接。

© www.soinside.com 2019 - 2024. All rights reserved.