套接字超时并删除O_NONBLOCK选项

时间:2011-02-22 22:39:25

标签: c sockets network-programming blocking nonblocking

我实现了套接字超时并重试但是为了做到这一点,我必须将套接字设置为非阻塞套接字。但是,我需要套接字来阻止。这是我尝试解决这两个问题。这不起作用。后续发送调用阻止但从不发送任何数据。当我没有选择和超时连接时,后续的发送调用正常工作。

参考文献:

代码:

fd_set fdset;
struct timeval tv;
fcntl(dsock, F_SETFL, O_NONBLOCK);
tv.tv_sec = theDeviceTimeout;
tv.tv_usec = 0;
int retries=0;
logi(theLogOutput, LOG_INFO, "connecting to device socket num retrys: %i", theDeviceRetry);
for(retries=0;retries<theDeviceRetry;retries++) {
    connect(dsock, (struct sockaddr *)&daddr, sizeof daddr);


    FD_ZERO(&fdset);
    FD_SET(dsock, &fdset);
    if (select(dsock + 1, NULL, &fdset, NULL, &tv) == 1) {
        int so_error;
        socklen_t slen = sizeof so_error;
        getsockopt(dsock, SOL_SOCKET, SO_ERROR, &so_error, &slen);
        if (so_error == 0) {
            logi(theLogOutput, LOG_INFO, "connected to socket on port %i on %s", theDevicePort, theDeviceIP);
            break;
        } else {
            logi(theLogOutput, LOG_WARN, "connect to %i failed on ip %s because %s retries %i", theDevicePort, theDeviceIP, strerror(errno), retries);
            logi(theLogOutput, LOG_WARN, "failed to connect to device %s", strerror(errno));
            logi(theLogOutput, LOG_WARN, "error: %i %s", so_error, strerror(so_error));
            continue;
        }
    }
}

int opts;
opts = fcntl(dsock,F_GETFL);
logi(theLogOutput, LOG_DEBUG, "clearing nonblock option %i retries %i", opts, retries);
opts ^= O_NONBLOCK;
fcntl(dsock, F_SETFL, opts);

2 个答案:

答案 0 :(得分:1)

在获得可写事件并且没有错误之后,您需要再次调用connect(),如文档所述。这会告诉您连接是成功还是失败。

答案 1 :(得分:0)

为什么不使用SO_RCVTIMEOSO_SNDTIMEO套接字选项?或者我在你的问题中遗漏了什么?