ZBLOG

c++ socket connect 非阻塞 超时时间 判断

在C++中,可以使用非阻塞的方式来进行socket连接,并设置超时时间来判断连接是否超时。下面是一个简单的示例代码:

#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>

int connectNonBlocking(const char* ip, int port, int timeout) {
    // 创建socket
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        perror("socket");
        return -1;
    }

    // 设置非阻塞
    int flags = fcntl(sockfd, F_GETFL, 0);
    fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);

    // 构建服务器地址结构体
    struct sockaddr_in serverAddr{};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(port);
    if (inet_pton(AF_INET, ip, &(serverAddr.sin_addr)) <= 0) {
        perror("inet_pton");
        close(sockfd);
        return -1;
    }

    // 非阻塞connect,立即返回
    if (connect(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {
        if (errno != EINPROGRESS) {  // 连接错误,返回失败
            perror("connect");
            close(sockfd);
            return -1;
        }
        
        fd_set writeSet;
        FD_ZERO(&writeSet);
        FD_SET(sockfd, &writeSet);

        struct timeval tv;
        tv.tv_sec = timeout;  // 超时时间设置为timeout秒
        tv.tv_usec = 0;

        // 使用select等待连接成功或超时
        int ret = select(sockfd + 1, NULL, &writeSet, NULL, &tv);
        if (ret == -1) {  // 出错
            perror("select");
            close(sockfd);
            return -1;
        } else if (ret == 0) {  // 超时
            std::cout << "Connect timeout" << std::endl;
            close(sockfd);
            return -1;
        }

        // 连接成功或失败,检查错误码
        int error = 0;
        socklen_t len = sizeof(error);
        getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len);
        if (error != 0) {
            std::cout << "Connect failed: " << strerror(error) << std::endl;
            close(sockfd);
            return -1;
        }
    }

    // 非阻塞连接成功
    std::cout << "Connect succeeded" << std::endl;

    // 恢复为阻塞模式(可选)
    fcntl(sockfd, F_SETFL, flags);

    // 在这里可以继续进行后续的操作

    return sockfd;
}

int main() {
    const char* ip = "127.0.0.1";
    int port = 8080;
    int timeout = 5;  // 超时时间设置为5秒

    int sockfd = connectNonBlocking(ip, port, timeout);
    
    if (sockfd != -1) {
        // 连接成功,可以进行后续的操作
        
       close(sockfd); 
    }
    
   return 0; 
}

在上述代码中,connectNonBlocking 函数实现了非阻塞连接,并设置了超时时间。首先,将socket设置为非阻塞模式,然后进行connect操作。如果连接返回的错误码是EINPROGRESS,表示连接正在进行中,则使用select函数等待连接成功或超时。

select返回0时,表示连接超时;当select返回大于0时,需要进一步检查错误码来确定连接是否成功。如果连接失败,则可以根据具体的错误码进行相应的处理。

注意,在上述代码中仅展示了基本的非阻塞连接和超时判断逻辑,并未对异常情况进行完全处理,请根据实际需求进行适当调整和优化。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=5154

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?