如何在C语言中判断socket是否已经断开

 更新时间:2019年05月20日 14:25:37   作者:Anyanyamy  
如果不主动关闭socket的话,系统不会自动关闭的,除非当前进程挂掉了,操作系统把占用的socket回收了才会关闭。小编今天跟大家简单介绍下如何在C语言中判断socket是否已经断开

下面来介绍判断非阻塞SOCKET是否已经断开的几种方法:

注意要区分不同操作系统分别进行测试, 包括WINDOWS, LINUX和UNIX会各有不同。

在WINDOWS下比较简单,可以使用FD_CLOSE事件判断SOCKET是否已经断开

view plaincopy to clipboardprint?
bool IsSocketClosed(SOCKET clientSocket) 
{ 
 bool ret = false; 
 HANDLE closeEvent = WSACreateEvent(); 
 WSAEventSelect(clientSocket, closeEvent, FD_CLOSE); 
 
 DWORD dwRet = WaitForSingleObject(closeEvent, 0); 
 
 if(dwRet == WSA_WAIT_EVENT_0) 
 ret = true; 
 else if(dwRet == WSA_WAIT_TIMEOUT) 
 ret = false; 
 
 WSACloseEvent(closeEvent); 
 return ret; 
} 
 

在UNIX/LINUX下,非阻塞模式SOCKET可以采用recv+MSG_PEEK的方式进行判断,其中MSG_PEEK保证了仅仅进行状态判断,而不影响数据接收

对于主动关闭的SOCKET, recv返回-1,而且errno被置为9(#define EBADF   9 /* Bad file number */)

或104 (#define ECONNRESET 104 /* Connection reset by peer */)

对于被动关闭的SOCKET,recv返回0,而且errno被置为11(#define EWOULDBLOCK EAGAIN /* Operation would block */)

对正常的SOCKET, 如果有接收数据,则返回>0, 否则返回-1,而且errno被置为11(#define EWOULDBLOCK EAGAIN /* Operation would block */)

因此对于简单的状态判断(不过多考虑异常情况),
    recv返回>0,   正常
    返回-1,而且errno被置为11  正常
    其它情况    关闭

view plaincopy to clipboardprint?
#include <errno.h> 
 
bool IsSocketClosed(int clientSocket) 
{ 
 char buff[32]; 
 int recvBytes = recv(clientSocket, buff, sizeof(buff), MSG_PEEK); 
 
 int sockErr = errno; 
 
 //cout << "In close function, recv " << recvBytes << " bytes, err " << sockErr << endl; 
 
 if( recvBytes > 0) //Get data 
 return false; 
 
 if( (recvBytes == -1) && (sockErr == EWOULDBLOCK) ) //No receive data 
 return false; 
 
 return true; 
} 

此外,所有操作系统上还可以通过TCP_KEEPLIVE实行心跳检测。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • OpenCV获取图像中直线上的数据具体流程

    OpenCV获取图像中直线上的数据具体流程

    对图像进行处理时,经常会有这类需求:客户想要提取出图像中某条直线或者ROI区域内的感兴趣数据,进行重点关注,怎么操作呢,下面小编通过实例代码介绍下OpenCV获取图像中直线上的数据,一起看看吧
    2021-11-11
  • 用c 获取文件MD5值的实现方法

    用c 获取文件MD5值的实现方法

    本篇文章是对用c语言获取文件MD5值的方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++中实现子进程执行和管道通信详解

    C++中实现子进程执行和管道通信详解

    在这篇博客中,我们将深入探索如何在 C++ 程序中实现子进程的创建与执行,以及父子进程间的管道通信,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • C++ Qt属性系统详细介绍

    C++ Qt属性系统详细介绍

    这篇文章主要介绍了C++ Qt属性系统详细介绍的相关资料,需要的朋友可以参考下
    2016-12-12
  • C语言实现自行车存放管理系统

    C语言实现自行车存放管理系统

    这篇文章主要为大家详细介绍了C语言实现自行车存放管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • C++基于Boost库实现命令行解析

    C++基于Boost库实现命令行解析

    Boost库中默认自带了一个功能强大的命令行参数解析器,以往我都是自己实现参数解析的,今天偶尔发现这个好东西,就来总结一下参数解析的基本用法,该库需要引入program_options.hpp头文件,即可使用了
    2021-06-06
  • Qt出现假死冻结现象的原因及解决方法

    Qt出现假死冻结现象的原因及解决方法

    应用程序出现假死或冻结现象通常是由于一些常见问题所导致的,本文主要介绍了Qt出现假死冻结现象的原因及解决方法,具有一定的参考价值,感兴趣的可以了解一下
    2023-10-10
  • VC程序在Win32环境下动态链接库(DLL)编程原理

    VC程序在Win32环境下动态链接库(DLL)编程原理

    这篇文章主要介绍了VC程序在Win32环境下动态链接库(DLL)编程原理,包括了dll文件的原理与具体实现过程,对于深入掌握VC程序设计具有很好的参考借鉴价值,需要的朋友可以参考下
    2014-10-10
  • C语言进阶输入输出重定向与fopen函数使用示例详解

    C语言进阶输入输出重定向与fopen函数使用示例详解

    这篇文章主要为大家介绍了C语言进阶输入输出重定向与fopen函数的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-02-02
  • C++三元表达式详情

    C++三元表达式详情

    这篇文章主要介绍了C++三元表达式,文章围绕C++三元表达式的相关资料展开详细内容,需要的朋友可以参考一下,希望多你有所帮助
    2021-11-11

最新评论