当前位置: 首页 > news >正文

Linux或Windows下判断socket连接状态

前言

场景:客户端程序需要实时知道和服务器的连接状态。比较通用的做法应用层是采用心跳机制,每隔一端时间发送心跳能回复说明服务器正常。
实际应用场景中,服务端和客户端并不是一家厂商的,比如说笔者这种情况,服务端是其他厂商,应用层协议没有心跳机制,客户端显示的连接状态需要客户端自己处理。
笔者最开始使用的QTcpSocket进行socket连接,在客户端程序监听下面3个信息。

void disconnected()
void error(QAbstractSocket::SocketError socketError)
void stateChanged(QAbstractSocket::SocketState socketState)

笔者这边的测试结果是,第一次关闭服务器端口,客户端能检测到error信号,能获取到错误信息" The remote host closed the connection "
再次启动服务器端口,客户端使用同一个socket再次成功连接后,再次关闭服务器端口就检测不到断开信号,自此之后就再监测不到socket被断开的情况。

参考了网络上1篇文章
https://www.cnblogs.com/tomato0906/articles/4697098.html
文章并没有实际测试代码但提供了解决思路,判断socket是否已经断开的方法是使用非阻塞的select方式进行socket检查,笔者在Linux下使用这种方式没生效,
总的解决思路是使用 非阻塞的socket,使用recv函数进行判断。
换了个写法。直接采用 非阻塞的socket 使用recv + peek 的方式进行连接状态检查。

代码

使用windows平台(vs2013) 和 ubuntu 平台,服务器采用网络调试助手模拟,服务器socket主动断开,客户端能及时检测到,检测的及时性取决于SocketIsDisconn函数调用的频率。
具体测试代码及详细说明如下:

main.cpp

//#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>#ifdef WIN32
#include <Ws2tcpip.h>
#include <winsock2.h>// Need to link with Ws2_32.lib
#pragma comment(lib, "ws2_32.lib")#else#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <stdbool.h>
#include <errno.h>
#endifbool SocketIsDisconn(int sockfd)
{char buf[32] = { 0 };// 采用 recv + peek的方式进行数据读取进行连接状态的判断。int recvLen = recv(sockfd, buf, sizeof(buf), MSG_PEEK);/*recv函数说明:Windows: 如果未发生错误, recv 将返回收到的字节数, buf 参数指向的缓冲区将包含接收的此数据。 如果连接已正常关闭,则返回值为零。否则,将返回值 SOCKET_ERROR(值为-1),并且可以通过调用 WSAGetLastError 来检索特定的错误代码。Linux: These calls return the number of bytes received, or -1 if an error occurred.  In the event of an error, errno is set to indicate the error.  The return value will be 0 when the peer  has  per‐formed an orderly shutdown. 翻译过来和Windows说明类似,发生错误返回-1 从errno获取错误码,当另一端按顺序关闭时,返回值为0。Windows错误码:WSAEWOULDBLOCK: 资源暂时不可用。此错误是从无法立即完成的非阻止套接字上的操作返回的,例如,在没有排队要从套接字读取数据时进行 recv 。 这是一个非致命错误,应稍后重试该操作。 WSAEWOULDBLOCK 在非阻止SOCK_STREAM套接字上调用 连接是正常的,因为必须经过一段时间才能建立连接。Linux错误码: EAGAIN          Resource temporarily unavailable (may be the same value as EWOULDBLOCK) (POSIX.1) EWOULDBLOCK     Operation would block (may be same value as EAGAIN) (POSIX.1)错误码和Windows也是类型的。这里我们区分3种情况: 1.recv返回值大于0 正常收到数据,连接状态。2.recv返回值为-1 errCode为 WSAEWOULDBLOCK/EWOULDBLOCK 表明没读取到数据但是可以稍后再读,仍为连接状态。3.recv返回值为0 连接断开状态,其他错误情况 这里统一认为连接断开状态。*/#ifdef WIN32int errCode = WSAGetLastError();
#elseint errCode = errno;
#endifif (recvLen > 0){return false;}#ifdef WIN32if ((recvLen == -1) && (errCode == WSAEWOULDBLOCK))
#elseif ((recvLen == -1) && (errCode == EWOULDBLOCK))
#endif{return false;}return true;
}int main()
{
#ifdef WIN32// Initialize WinsockWSADATA wsaData;int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);if (iResult != NO_ERROR) {printf("WSAStartup function failed with error: %d\n", iResult);return 1;}SOCKET sockfd;
#elseint sockfd;
#endifint len;struct sockaddr_in address;int result;sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);address.sin_family = AF_INET;address.sin_addr.s_addr = inet_addr("192.168.11.213");address.sin_port = htons(9201);len = sizeof(address);result = connect(sockfd, (struct sockaddr *)&address, len);if (result == -1) {
#ifdef WIN32printf("socket function failed with error: %ld\n", WSAGetLastError());WSACleanup();getchar();
#elseperror("connect error:");
#endifexit(1);}//设置socket套接字为非阻塞
#ifdef WIN32DWORD argp = 1;ioctlsocket(sockfd, FIONBIO, &argp);
#elseint old_flag = fcntl(sockfd, F_GETFL, 0);int new_flag = old_flag | O_NONBLOCK;fcntl(sockfd, F_SETFL, new_flag);
#endif//循环检查连接状态,断开则退出循环while (1){printf("check...\n");
#ifdef WIN32Sleep(3000);
#elsesleep(3);
#endifbool bClose = SocketIsDisconn(sockfd);printf("bDisconn:%d\n", bClose);if (bClose){break;}}
#ifdef WIN32closesocket(sockfd);getchar();
#elseclose(sockfd);
#endifexit(0);
}

Linux 下,直接gcc编译运行,windows下需要用vs2013 打开项目文件然后编译运行,整个项目下载。

相关文章:

Linux或Windows下判断socket连接状态

前言 场景&#xff1a;客户端程序需要实时知道和服务器的连接状态。比较通用的做法应用层是采用心跳机制&#xff0c;每隔一端时间发送心跳能回复说明服务器正常。 实际应用场景中&#xff0c;服务端和客户端并不是一家厂商的&#xff0c;比如说笔者这种情况&#xff0c;服务端…...

编译链接实战(25)gcc ASAN、MSAN检测内存越界、泄露、使用未初始化内存等内存相关错误

文章目录 1 ASAN1.1 介绍1.2 原理编译时插桩模块运行时库2 检测示例2.1 内存越界2.2 内存泄露内存泄露检测原理作用域外访问2.3 使用已经释放的内存2.4 将漏洞信息输出文件3 MSAN1 ASAN 1.1 介绍 -fsanitize=address是一个编译器选项,用于启用AddressSanitizer(地址...

[HackMyVM]靶场 VivifyTech

kali:192.168.56.104 主机发现 arp-scan -l # arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:d2:e0:49, IPv4: 192.168.56.104 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.56.1 0a:00:27:00:00:05 (Unk…...

软考高级系统分析师:关联关系、依赖关系、实现关系和泛化关系概念和例题

一、AI 解读 关联关系、依赖关系、实现关系和泛化关系是面向对象设计中的四种基本关系。它们在类与类之间建立不同类型的联系&#xff0c;以反映对象间的相互作用、依赖和继承关系。下面我将使用表格的形式来解释这四种关系的概念和它们之间的区别&#xff1a; 关系类型概念特…...

设计模式学习笔记 - 面向对象 - 9.实践:如何进行面向对象分析、设计与编码

1.如何对接口鉴权这样一个功能开发做面向对象分析 本章会结合一个真实的案例&#xff0c;从基础的需求分析、职责划分、类的定义、交互、组装运行讲起&#xff0c;将最基础的面向对象分析&#xff08;00A&#xff09;、设计&#xff08;00D&#xff09;、编程&#xff08;00P&…...

【iOS ARKit】RealityKit 同步机制

协作 Session 可以很方便地实现多用户之间的AR体验实时共享&#xff0c;但开发者需要自行负责并确保AR场景的完整性&#xff0c;自行负责虚拟物体的创建与销毁。为简化同步操作&#xff0c;RealityKit 内建了同步机制&#xff0c;RealityKit 同步机制基于 Multipeer Connectivi…...

【数据结构与算法】整数二分

问题描述 对一个排好序的数组&#xff0c;要求找到大于等于7的最小位置和小于等于7的最大位置 大于等于7的最小位置 易知从某个点开始到最右边的边界都满足条件&#xff0c;我们要找到这个区域的最左边的点。 开始二分&#xff01; left指针指向最左边界&#xff0c;right…...

java项目打包运行报异常:xxxxx-1.0-SNAPSHOT.jar中没有主清单属性

pom.xml中加入这段话即可 <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.4.4</version><executions><execution><…...

MAC-键盘command快捷键、设置windows快捷键

在 Windows PC 专用键盘上&#xff0c;请用 Alt 键代替 Option 键&#xff0c;用 Ctrl 键或 Windows 标志键代替 Command 键。 Mac 键盘快捷键 - 官方 Apple 支持 (中国) 设置windows快捷键 使用mac外接适用于windows的键盘时&#xff0c;如何设置快捷键&#xff1f;_mac外…...

C++ 补充之常用遍历算法

C遍历算法和原理 C标准库提供了丰富的遍历算法&#xff0c;涵盖了各种不同的功能。以下是一些常见的C遍历算法以及它们的概念和原理的简要讲解&#xff1a; for_each&#xff1a;对容器中的每个元素应用指定的函数。 概念&#xff1a;对于给定的容器和一个可调用对象&#xff…...

【Linux杂货铺】调试工具gdb的使用

目录 &#x1f308;前言&#x1f308; &#x1f4c1;背景介绍 &#x1f4c1; 使用 list [行号] / [函数名] run/r break/b [行号] / [函数名] info break disable break enable break delete break [断点编号] next/n step/s continue/c finish print/p [变量…...

FL Studio Producer Edition2024中文进阶版Win/Mac

FL Studio Producer Edition&#xff0c;特别是其【中文进阶版 Win/Mac】&#xff0c;是数字音乐制作领域中的一款知名软件。它为广大音乐制作人、声音工程师以及音乐爱好者提供了一个从音乐构思到最终作品发布的完整解决方案。这个版本特别为中文用户优化&#xff0c;并兼容W…...

无需邀请码,Xinstall实现精准分享归因

在如今的移动互联网时代&#xff0c;分享已经成为了我们日常生活中不可或缺的一部分。无论是社交媒体上的好友分享&#xff0c;还是应用内的内容分享&#xff0c;分享都能够帮助我们快速传播信息&#xff0c;扩大影响力。然而&#xff0c;对于开发者而言&#xff0c;分享却带来…...

机器人与AGI会撞出什么火花?

真正的科技变革是不是就要来临了&#xff1f;各方大佬都开始布局机器人&#xff0c;对于普通人的就业会造成什么影响&#xff1f; ​ 优牛企讯-企业动态信息监控专家 在优牛企讯-企业动态监控专家搜索可知&#xff0c;全国目前的机器人公司已经达到了26401家&#xff0c;近一年…...

Linux yum安装pgsql出现Bad GPG signature错误

官方文档&#xff1a;https://www.postgresql.org/download/linux/redhat/ sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm sudo yum install -y postgresql12-server sudo /usr/pgsql-12/bin/…...

第18章-DHCP

1. 产生背景 2. 概述 2.1 定义 2.2 特点 2.3 DHCP系统组成 3. DHCP工作原理 3.1 前提条件 3.2 场景 3.3 分配IP地址工作机制 3.4 特殊情况处理 3.5 IP地址租约更新 4. DHCP中继代理 4.1 现实场景 4.2 工作机制 1. 产生背景 现实问题&#xff1a; 小型网络中&…...

[物联网] OneNet 多协议TCP透传

[物联网] OneNet 多协议TCP透传 STM32物联网–ONENET云平台的多协议接入产品创建 : https://blog.csdn.net/qq_44942724/article/details/134492924 Onenet tcp 透传 : https://blog.csdn.net/flyme2010/article/details/107086001 tcp服务端测试工具 : http://tcp.xnkiot.com/…...

如何让网页APP化 渐进式Web应用(PWA)

前言 大家上网应该发现有的网页说可以安装对应应用&#xff0c;结果这个应用好像就是个web&#xff0c;不像是应用&#xff0c;因为这里采用了PWA相关技术。 PWA&#xff0c;全称为渐进式Web应用&#xff08;Progressive Web Apps&#xff09;&#xff0c;是一种可以提供类似…...

50 vmalloc 的实现

前言 这里说的是 内核中分配按页分配的场景 常用于 驱动什么的, 分配 中大型空间 由于 连续的 n 个页是分别使用 alloc_pages 分配的, 因此是 虚拟地址空间连续, 但是 物理地址空间不连续 如何分配对象 两个步骤, __get_vm_area_node 获取为 size 分配的 vma 区间, 然后…...

程序员的金三银四求职宝典!

目录 ​编辑 程序员的金三银四求职宝典 一、为什么金三银四是程序员求职的黄金时期&#xff1f; 二、如何准备金三银四求职&#xff1f; 1. 完善简历 2. 增强技术能力 3. 提前考虑目标公司 4. 提前准备面试 三、程序员求职的常见面试题 1. 数据结构和算法 2. 数据库 …...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

DAY 26 函数专题1

函数定义与参数知识点回顾&#xff1a;1. 函数的定义2. 变量作用域&#xff1a;局部变量和全局变量3. 函数的参数类型&#xff1a;位置参数、默认参数、不定参数4. 传递参数的手段&#xff1a;关键词参数5 题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一…...

数据分析六部曲?

引言 上一章我们说到了数据分析六部曲&#xff0c;何谓六部曲呢&#xff1f; 其实啊&#xff0c;数据分析没那么难&#xff0c;只要掌握了下面这六个步骤&#xff0c;也就是数据分析六部曲&#xff0c;就算你是个啥都不懂的小白&#xff0c;也能慢慢上手做数据分析啦。 第一…...

python读取SQLite表个并生成pdf文件

代码用于创建含50列的SQLite数据库并插入500行随机浮点数据&#xff0c;随后读取数据&#xff0c;通过ReportLab生成横向PDF表格&#xff0c;包含格式化&#xff08;两位小数&#xff09;及表头、网格线等美观样式。 # 导入所需库 import sqlite3 # 用于操作…...