0

0

C++网络编程异常 连接超时处理方案

P粉602998670

P粉602998670

发布时间:2025-08-25 10:15:01

|

394人浏览过

|

来源于php中文网

原创

答案:C++中推荐使用非阻塞socket结合select或poll实现连接超时,通过设置非阻塞模式并监听写事件,配合超时参数和SO_ERROR检查,可精准控制连接尝试时间,提升程序健壮性;多线程异步方案适用于低并发场景,而避免使用非标准的SO_SNDTIMEO或信号处理机制。

c++网络编程异常 连接超时处理方案

在C++网络编程中,连接超时是常见问题,尤其在网络环境不稳定或目标服务器无响应时。如果不做处理,connect() 等函数可能会阻塞数分钟,严重影响程序响应。合理设置超时机制,能提升程序健壮性和用户体验。

1. 使用非阻塞socket + select()

将socket设为非阻塞模式,在调用 connect() 后立即返回。通过 select() 监听socket是否可写,判断连接是否成功建立。

步骤如下:

  • 创建socket,使用 fcntl()(Linux)或 ioctlsocket()(Windows)将其设为非阻塞
  • 调用 connect(),若返回 -1 且 errno 为 EINPROGRESS(Linux)或 WSAEWOULDBLOCK(Windows),表示连接正在尝试中
  • 使用 select() 设置超时时间,监听该socket的写事件
  • select 返回后,通过 getsockopt() 检查 socket 的 SO_ERROR 选项,确认连接是否成功
示例代码片段(Linux):
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
fcntl(sockfd, F_SETFL, O_NONBLOCK);

connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));

fd_set write_fds;
struct timeval tv = {5, 0}; // 5秒超时
FD_ZERO(&write_fds);
FD_SET(sockfd, &write_fds);

if (select(sockfd + 1, NULL, &write_fds, NULL, &tv) > 0) {
    int so_error;
    socklen_t len = sizeof(so_error);
    getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &so_error, &len);
    if (so_error == 0) {
        // 连接成功
    } else {
        // 连接失败
    }
} else {
    // 超时或错误
}

2. 使用 poll() 替代 select()

poll() 是 select 的现代替代,支持更多文件描述符,接口更清晰。

立即学习C++免费学习笔记(深入)”;

用法类似:将socket加入 pollfd 数组,关注 POLLOUT 事件,设置超时毫秒数。

讯飞智作-讯飞配音
讯飞智作-讯飞配音

讯飞智作是一款集AI配音、虚拟人视频生成、PPT生成视频、虚拟人定制等多功能的AI音视频生产平台。已广泛应用于媒体、教育、短视频等领域。

下载
  • 调用 connect() 后,socket处于连接中状态
  • poll() 返回 > 0 且 revents 包含 POLLOUT,表示连接就绪
  • 仍需 getsockopt() 检查 SO_ERROR 判断连接成败

3. 设置connect()系统级超时(不推荐)

某些系统允许通过 SO_SNDTIMEO 设置 connect 超时,但此行为非标准,跨平台兼容性差,Windows 和 Linux 表现不一致,建议避免使用。

4. 结合信号处理(SIGALRM)

仅适用于单线程程序。使用 alarm() 设置定时器,超时后触发 SIGALRM 信号中断 connect()。

  • 需设置信号处理函数
  • connect() 被中断后返回 -1,errno 为 EINTR
  • 多线程环境下信号处理复杂,易出错,不推荐

5. 多线程异步连接

在子线程中执行阻塞 connect(),主线程使用 std::future::wait_for() 控制超时。

  • 简单直观,适合现代C++项目
  • 避免手动处理非阻塞IO
  • 注意线程资源开销,高并发场景慎用
示例:
auto future = std::async(std::launch::async, [&]() {
    return connect(sockfd, ...);
});
if (future.wait_for(std::chrono::seconds(5)) == std::future_status::timeout) {
    // 超时处理
}

基本上就这些。推荐使用非阻塞 socket + select/poll 方案,控制精细,性能好。多线程方案适合对并发要求不高的场景。关键是要统一错误处理逻辑,确保超时和连接失败都能被正确识别和响应。

相关专题

更多
硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

989

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

50

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

214

2025.12.29

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

471

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

107

2025.12.24

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

107

2025.12.24

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

516

2023.07.26

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1051

2023.07.27

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 5.7万人学习

C 教程
C 教程

共75课时 | 3.8万人学习

C++教程
C++教程

共115课时 | 10.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号