C++自定义connect超时时间——非阻塞套接字法

2023-11-15

一 代码

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <string.h>

#define BUFFER_SIZE 1023

int setnonblocking( int fd )     //设置套接字为非阻塞套接字
{
    int old_option = fcntl( fd, F_GETFL );
    int new_option = old_option | O_NONBLOCK;
    fcntl( fd, F_SETFL, new_option );
    return old_option;
}

int unblock_connect( const char* ip, int port, int time )
{
    int ret = 0;
    struct sockaddr_in address;
    bzero( &address, sizeof( address ) );
    address.sin_family = AF_INET;
    inet_pton( AF_INET, ip, &address.sin_addr );
    address.sin_port = htons( port );

    int sockfd = socket( PF_INET, SOCK_STREAM, 0 );
    int fdopt = setnonblocking( sockfd );      //套接字设置为非阻塞套接字     
    ret = connect( sockfd, ( struct sockaddr* )&address, sizeof( address ) );
    printf("connect ret code = %d\n", ret);
    if ( ret == 0 )
    {
        printf( "connect with server immediately\n" );
        fcntl( sockfd, F_SETFL, fdopt );   //set old optional back
        return sockfd;
    }
    //unblock mode --> connect return immediately! ret = -1 & errno=EINPROGRESS
    else if ( errno != EINPROGRESS )
    {
        printf("ret = %d\n", ret);
        printf( "unblock connect failed!\n" );
        return -1;
    }
    else if (errno == EINPROGRESS)
    {
        printf( "unblock mode socket is connecting...\n" );
    }

    //use select to check write event, if the socket is writable, then
    //connect is complete successfully!
    fd_set readfds;
    fd_set writefds;
    struct timeval timeout;

    FD_ZERO( &readfds );
    FD_SET( sockfd, &writefds );

    timeout.tv_sec = time; //我们设置超时时间为1秒,原来大概需要3秒
    timeout.tv_usec = 0;

    ret = select( sockfd + 1, NULL, &writefds, NULL, &timeout );
    if ( ret <= 0 )
    {
        printf( "connection time out\n" );
        close( sockfd );
        return -1;
    }

    if ( ! FD_ISSET( sockfd, &writefds  ) )
    {
        printf( "no events on sockfd found\n" );
        close( sockfd );
        return -1;
    }

    int error = 0;
    socklen_t length = sizeof( error );
    if( getsockopt( sockfd, SOL_SOCKET, SO_ERROR, &error, &length ) < 0 )
    {
        printf( "get socket option failed\n" );
        close( sockfd );
        return -1;
    }

    if( error != 0 )
    {
        printf( "connection failed after select with the error: %d \n", error );
        close( sockfd );
        return -1;
    }

    //connection successful!
    printf( "connection ready after select with the socket: %d \n", sockfd );
    fcntl( sockfd, F_SETFL, fdopt ); //set old optional back
    return sockfd;
}

int main( int argc, char* argv[] )
{
    if( argc <= 2 )
    {
        printf( "usage: %s ip_address port_number\n", basename( argv[0] ) );
        return 1;
    }
    const char* ip = argv[1];
    int port = atoi( argv[2] );

    int sockfd = unblock_connect( ip, port, 1);  //这个值可以修改为5秒作测试
    if ( sockfd < 0 )
    {
        printf("sockfd error! return -1\n");
        return 1;
    }
    //shutdown( sockfd, SHUT_WR ); //disable read and write
    printf( "send data out\n" );
    send( sockfd, "abc", 3, 0 );
    shutdown( sockfd, SHUT_WR ); //disable read and write
    close(sockfd);
    return 0;
}

二 运行

[root@localhost test]# g++ test.cpp -o test
[root@localhost test]# ./test 192.168.0.111 11133 kkk              //该IP不存在
connect ret code = -1
unblock mode socket is connecting...
connection time out
sockfd error! return -1
[root@localhost test]# ./test 192.168.0.110 11133 kkk              //该IP是本机IP
connect ret code = -1
unblock mode socket is connecting...
connection failed after select with the error: 111
sockfd error! return -1

如果把超时时间修改为5秒

[root@localhost test]# ./test 192.168.0.112 11133 kkk
connect ret code = -1
unblock mode socket is connecting...
connection failed after select with the error: 113
sockfd error! return -1

三 说明

1 SO_ERROR参考

https://blog.csdn.net/feng973/article/details/53463750

2 常见SO_ERROR

#define ECONNREFUSED    111 /* Connection refused */
#define EHOSTDOWN   112 /* Host is down */
#define EHOSTUNREACH    113 /* No route to host */

3 代码中自定义函数setnonblocking,用于设置套接字为非阻塞套接字。然后定义一个函数unblock_connect用于连接,并且设置为1秒作为超时时间。而实际的超时返回是通过select函数来实现的。

192.168.0.111是Linux主机IP的同一网段的一个假IP,原来阻塞超时3秒作用,所以修改为1秒后,会走超时分支,说明我们自定义的超时生效了。

192.168.0.110是本机IP,它返回的错误码是111,拒绝连接。

192.168.0.111是Linux主机IP的同一网段的一个假IP,把代码的超时时间从1秒改为5秒,连接错误码是113,即没有路由到主机。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++自定义connect超时时间——非阻塞套接字法 的相关文章

  • EF Core Group By 翻译支持条件总和

    听说 EF Core 2 1 将支持翻译小组 我感到非常兴奋 我下载了预览版并开始测试它 但发现我在很多地方仍然没有得到翻译分组 在下面的代码片段中 对 TotalFlagCases 的查询将阻止翻译分组工作 无论如何 我可以重写这个以便我
  • “构建”构建我的项目,“构建解决方案”则不构建

    我刚刚开始使用VS2010 我有一个较大的解决方案 已从 VS2008 成功迁移 我已将一个名为 Test 的控制台应用程序项目添加到解决方案中 选择构建 gt 构建解决方案不编译新项目 选择构建 gt 构建测试确实构建了项目 在失败的情况
  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • 用于检查类是否具有运算符/成员的 C++ 类型特征[重复]

    这个问题在这里已经有答案了 可能的重复 是否可以编写一个 C 模板来检查函数是否存在 https stackoverflow com questions 257288 is it possible to write a c template
  • 在 Windows 窗体中保存带有 Alpha 通道的单色位图会保存不同(错误)的颜色

    在 C NET 2 0 Windows 窗体 Visual Studio Express 2010 中 我保存由相同颜色组成的图像 Bitmap bitmap new Bitmap width height PixelFormat Form
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • WPF/C# 将自定义对象列表数据绑定到列表框?

    我在将自定义对象列表的数据绑定到ListBox in WPF 这是自定义对象 public class FileItem public string Name get set public string Path get set 这是列表
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • 基于 OpenCV 边缘的物体检测 C++

    我有一个应用程序 我必须检测场景中某些项目的存在 这些项目可以旋转并稍微缩放 更大或更小 我尝试过使用关键点检测器 但它们不够快且不够准确 因此 我决定首先使用 Canny 或更快的边缘检测算法 检测模板和搜索区域中的边缘 然后匹配边缘以查
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • 哪种 C 数据类型可以表示 40 位二进制数?

    我需要表示一个40位的二进制数 应该使用哪种 C 数据类型来处理这个问题 如果您使用的是 C99 或 C11 兼容编译器 则使用int least64 t以获得最大的兼容性 或者 如果您想要无符号类型 uint least64 t 这些都定

随机推荐

  • CTF签到题

    提示输入口令zhimakaimen 但是查看源代码发现输入框对长度有限制 最长只能输入10位 使用firefox插件firebug chrome控制台可直接对manlength值进行修改 改为大于11 即可输入 也可以使用burpsuite
  • Nginx常用命令以及升级(window)

    nginx Windows作为标准控制台应用程序 不是服务 运行 可以使用以下命令对其进行管理 start nginx 启动Nginx nginx s stop fast shutdown 快速停止 nginx s quit gracefu
  • 基础css-flex布局基础属性

    1 flex布局 弹性布局 伸缩布局 设置当前盒子为弹性盒子 display flex 设置主轴方向的对齐方式 justify content justify content center 设置侧轴方向的对齐方式 align items a
  • replace(),IndexOf(),substring() ,lastIndexOf() ,split() ,pollFirst() ,pollFirst()

    replace pattern replacement 使用replacement替换pattern 如果pattern是字符串只替换第一个匹配项 如果pattern是正则表达式则替换每次匹配都要调用的回调函数 实例 String a 1
  • win10 系统开启自带热点,手机无法连接(连接超时)

    win10开始自带热点 手机成功连接 颇费周折 所以在此记录一下 也给其他人一个参考 今天想在win10上安装个WIFI软件 好让手机连接 结果无意间发现win10自带了热点功能 于是赶紧打开 手机的WIFI列表也显示出来了 本以为就这样愉
  • 国际MES供应商与产品大全

    最近花了一点时间 将国际上知名的MES厂商和其产品整理了一下 如下 ABB ABB 苏黎世 瑞士 是一个240亿美元的自动化和电力技术的全球业务的供应商 它的制造软件利用其控制及自动化产品通用解决方案的一部分 其系统800xa控制体系结构
  • Android 自定义播放暂停按钮图片

    Android 自定义播放暂停按钮图片 在开发Android应用程序时 我们经常需要使用播放暂停按钮来控制媒体播放器的状态 虽然Android提供了默认的播放暂停按钮 但有时候我们希望根据设计需求自定义这些按钮的外观 在本文中 我将详细介绍
  • 嵌入式毕设分享 自动晾衣架设计与实现(源码+硬件+论文)

    文章目录 0 前言 1 主要功能 2 硬件设计 原理图 3 核心软件设计 4 实现效果 5 最后 0 前言 这两年开始毕业设计和毕业答辩的要求和难度不断提升 传统的毕设题目缺少创新和亮点 往往达不到毕业答辩的要求 这两年不断有学弟学妹告诉学
  • 解决tmux启动「can't create socket」的问题

    Tmux是终端重度用户的好帮手 你再也不用担心以下问题 任务运行一半要下班 发现忘记使用nohup 网络不稳定 终端会掉线 有人找我开会 切换有线 无线会掉线 我入职以后 一直在开发机里面使用tmux和screen 在我发现tmux之前 最
  • Java的循环

    目录 1 while循环 2 do while循环 3 for 循环 1 while循环 while循环结构 语法结构 初始值 while 条件 循环操作代码块 迭代代码 执行规律 1 首先执行一次初始值 2 然后判断条件 如果条件为tru
  • ESP32的WIFI的STA模式&调控ESP32蓝牙和WIFI发射功率

    以下相关API接口的定义可进入l乐鑫官方查看 Wi Fi 库 ESP32 ESP IDF 编程指南 v4 4 文档 STA模式配置过程 include
  • springboot 获取当前日期_Spring Boot获取时间

    运行环境新建测试类 package com wusiyao websockets service import org springframework stereotype Service import java text SimpleDa
  • 【Linux后端服务器开发】常用开发工具

    目录 一 apt yum 二 gcc g 三 make makefile 四 vi vim 五 gdb 一 apt yum apt 和 yum 都是在Linux环境下的软件包管理器 负责软件的查找 安装 更新与卸载 apt 是Ubuntu系
  • 小程序经典案例

    1 上拉触底事件 data colorList isloding false getColors this setData isloding true 需要展示 loading 效果 wx showLoading title 数据加载中 w
  • Java学习笔记 03

    相关文章 Java学习笔记 01 概论 Java学习笔记 02 快速之旅 Java环境配置及HelloWorld程序 引言 写这篇文章 主要是为了以后能快速复习Java的基础语法 同时 帮助有C 等语言基础的同学快速入门Java 目录 一
  • SmartFusion从FPGA到ARM系列教程

    前言 本系列教程 将会以Microsemi SmartFusion一代芯片A2F200M3F为例 简单介绍片上ARM Cortex M3 硬核 MCU 基本外设的使用 及其与FPGA逻辑模块进行交互的示例 在学习片上硬核ARM Cortex
  • 网上阅卷系统php源码,又开源了,网上阅卷系统自动识别功能代码

    想让自己轻松点就要让计算机多为你做点 前几天一个朋友找到我让我做一个网上阅卷系统 就是实现这么几个功能 高速扫描仪扫描试卷后得到一张一张的图片 软件的功能就是处理图片 计算成绩 再详细点就是自动识别考生涂的学号 自动识别考生的选择题答案并记
  • css设计引言,HTML5与CSS3设计模式 引言(3)

    引言 3 2 代码清单2 浮动下沉首字示例 HTML pclass hanging indent spanclass hanging dropcap H span anging Dropcap p CSS hanging indent pa
  • 2022-渗透测试-git提权(Linux)

    目录 1 什么是提权 2 git提权命令 3 git的使用 1 什么是提权 提权就是通过各种办法和漏洞 提高自己在服务器中的权限 以便控制全局 利用漏洞的最终目的是获取被测系统的最高权限 即Windows中管理员账户的权限 或Linux中r
  • C++自定义connect超时时间——非阻塞套接字法

    一 代码 include