117.info
人生若只如初见

linux 客户端 Socket 非阻塞connect编程

在Linux中,可以使用非阻塞IO(Non-blocking IO)来实现非阻塞connect的编程。

以下是一个简单的示例代码,演示如何在Linux中使用非阻塞connect进行Socket编程:

#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main() {
    // 创建Socket
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        std::cerr << "Failed to create socket." << std::endl;
        return 1;
    }

    // 设置Socket为非阻塞
    int flags = fcntl(sockfd, F_GETFL, 0);
    if (flags == -1) {
        std::cerr << "Failed to get socket flags." << std::endl;
        return 1;
    }
    if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1) {
        std::cerr << "Failed to set socket to non-blocking mode." << std::endl;
        return 1;
    }

    // 设置连接目标地址
    struct sockaddr_in server_addr{};
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(12345);
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");

    // 尝试非阻塞连接
    int ret = connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
    if (ret == -1) {
        if (errno == EINPROGRESS) {
            // 连接正在进行中,等待连接完成
            fd_set write_fds;
            FD_ZERO(&write_fds);
            FD_SET(sockfd, &write_fds);

            struct timeval timeout{};
            timeout.tv_sec = 5;  // 设置连接超时时间为5秒

            ret = select(sockfd + 1, nullptr, &write_fds, nullptr, &timeout);
            if (ret == -1) {
                std::cerr << "Failed to select." << std::endl;
                return 1;
            } else if (ret == 0) {
                // 连接超时
                std::cerr << "Connect timeout." << std::endl;
                return 1;
            } else {
                // 连接完成,检查连接是否成功
                int error = 0;
                socklen_t len = sizeof(error);
                if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) == -1) {
                    std::cerr << "Failed to get socket option." << std::endl;
                    return 1;
                }
                if (error != 0) {
                    std::cerr << "Failed to connect: " << strerror(error) << std::endl;
                    return 1;
                }
            }
        } else {
            std::cerr << "Failed to connect: " << strerror(errno) << std::endl;
            return 1;
        }
    }

    std::cout << "Connected successfully." << std::endl;

    // 连接成功后,可以进行后续操作

    close(sockfd);

    return 0;
}

在上述代码中,首先创建了一个Socket,并将其设置为非阻塞模式。然后,通过connect函数进行非阻塞连接。如果connect返回-1,并且errno为EINPROGRESS,说明连接正在进行中,此时可以通过select函数等待连接完成。如果select返回0,表示连接超时。如果select返回大于0,说明连接已完成,可以通过getsockopt函数获取连接结果。如果连接成功,可以进行后续操作。

注意,上述代码只是一个简单的示例,实际使用中可能需要根据具体情况进行适当的修改和优化。

未经允许不得转载 » 本文链接:https://www.117.info/ask/fedd0AzsLAwRRB1w.html

推荐文章

  • linux怎么为文件增加内容

    在Linux中,可以使用以下几种方法为文件增加内容: 使用echo命令将内容追加到文件末尾:
    echo "content" >> filename 例如,将"Hello World!"追加到文件exa...

  • 怎么用linux实现杨辉三角

    要在Linux上实现杨辉三角,可以使用shell脚本编写一个程序。下面是一个示例:
    #!/bin/bash echo -n "请输入要打印的行数:"
    read rows for (( i=0; i

  • linux内存释放不掉怎么解决

    如果Linux系统中的内存无法释放,可以尝试以下解决方案: 重启系统:这是最简单的解决方法,重启系统可以清空所有的内存,并重新分配给系统需要的进程。 使用内存...

  • Linux之环境变量永久生效怎么配置

    要使环境变量在Linux系统中永久生效,可以按照以下步骤进行配置: 打开终端或命令行界面。
    使用文本编辑器(如vi、nano等)打开用户的配置文件。具体命令如...

  • Android常用控件Spinner的使用

    Spinner是Android开发中常用的控件之一,用于显示下拉菜单的选项。以下是Spinner的使用方法: 在XML布局文件中添加Spinner控件: 在Java代码中获取Spinner控件的...

  • Ubuntu中安装gcc编译器

    要在Ubuntu中安装GCC编译器,您可以按照以下步骤进行操作: 打开终端 (Ctrl + Alt + T)。
    运行以下命令来更新包列表:sudo apt update
    运行以下命令来...

  • mysql中text,longtext,mediumtext区别

    在MySQL中,text、longtext和mediumtext都是用于存储文本数据类型的列。它们之间的区别如下: text:text类型可以存储最大长度为65,535个字符(约为64KB)的文本...

  • 如何配置jdk环境变量

    要配置JDK环境变量,您需要按照以下步骤进行操作: 首先,下载并安装JDK。
    找到JDK安装目录。默认情况下,JDK安装在"C:\Program Files\Java"(Windows)或"...