当前位置: 首页 > 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. 数据库 …...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...