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

要在C语言中判断socket是否已经断开,可以通过以下方式实现:

  1. 使用heartbeat机制:

可以使用心跳机制来判断socket是否已经断开。在socket连接建立之后,不断地在两端之间发送心跳包,如果一段时间内没有收到对端的心跳回复,则认为连接已经断开。

以下是使用heartbeat机制的示例代码:

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>

#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define HEARTBEAT_INTERVAL 10 // 心跳间隔,单位:秒
#define HEARTBEAT_TIMEOUT 20  // 心跳超时,单位:秒

int main() {
    int sockfd = -1;
    struct sockaddr_in server_addr;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket");
        return -1;
    }

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
    server_addr.sin_port = htons(SERVER_PORT);

    if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("connect");
        close(sockfd);
        return -1;
    }

    printf("Connected to server: %s:%d\n", SERVER_IP, SERVER_PORT);

    // 启动心跳线程
    pthread_t heartbeat_thread;
    pthread_create(&heartbeat_thread, NULL, heartbeat, (void*)&sockfd);

    // 此处可以进行socket通信
    ...

    // 等待心跳线程结束
    pthread_join(heartbeat_thread, NULL);

    close(sockfd);

    return 0;
}

void* heartbeat(void* arg) {
    int sockfd = *(int*)arg;

    while (1) {
        if (send(sockfd, "heartbeat", sizeof("heartbeat"), 0) < 0) {
            fprintf(stderr, "Failed to send heartbeat packet: %s\n", strerror(errno));
            return NULL;
        }

        sleep(HEARTBEAT_INTERVAL);

        // 检查是否收到心跳回复,如果超时则认为socket已经断开
        char buffer[1024] = {0};
        struct timeval timeout;
        fd_set read_fds;

        FD_ZERO(&read_fds);   
        FD_SET(sockfd, &read_fds);  

        timeout.tv_sec = HEARTBEAT_TIMEOUT;
        timeout.tv_usec = 0;

        if (select(sockfd + 1, &read_fds, NULL, NULL, &timeout) == 0) {
            fprintf(stderr, "Heartbeat timeout, socket disconnected\n");
            return NULL;
        }

        if (recv(sockfd, buffer, sizeof(buffer), 0) <= 0) {
            fprintf(stderr, "Failed to receive heartbeat reply: %s\n", strerror(errno));
            return NULL;
        }
    }

    return NULL;
}
  1. 使用select函数:

使用select函数可以监控socket的读事件,如果select返回值为0,则表示socket已经断开。

以下是使用select函数的示例代码:

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080

int main() {
    int sockfd = -1;
    struct sockaddr_in server_addr;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("socket");
        return -1;
    }

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
    server_addr.sin_port = htons(SERVER_PORT);

    if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("connect");
        close(sockfd);
        return -1;
    }

    printf("Connected to server: %s:%d\n", SERVER_IP, SERVER_PORT);

    while (1) {
        fd_set read_fds;
        struct timeval timeout;

        FD_ZERO(&read_fds);
        FD_SET(sockfd, &read_fds);

        timeout.tv_sec = 5;
        timeout.tv_usec = 0;

        if (select(sockfd + 1, &read_fds, NULL, NULL, &timeout) <= 0) {
            fprintf(stderr, "Socket disconnected\n");
            break;
        }

        // 接收来自服务器的消息
        ...
    }

    close(sockfd);

    return 0;
}

使用上述两种方式可以有效判断socket是否已经断开,根据不同的需求选择不同的实现方式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:如何在C语言中判断socket是否已经断开 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • windows系统下C++调用matlab程序的方法详解

    针对“windows系统下C++调用matlab程序的方法详解”的问题,我会给出一个完整的攻略: Windows系统下C++调用Matlab程序的方法详解 介绍 在开发过程中,有时需要使用到Matlab算法或函数,为了快速地实现使用Matlab,可以将算法或函数编写成Matlab可执行文件(.exe),并通过C++程序进行调用。在Windows系统下,我们可…

    C 2023年5月23日
    00
  • js 将json字符串转换为json对象的方法解析

    下面是关于 “js 将json字符串转换为json对象的方法解析” 的完整攻略: 什么是 JSON JSON(JavaScript Object Notation)是一种轻量级数据交换格式。JSON 被设计成易于读写和解析,同时也易于生成和解析。JSON 使用 JavaScript 语法,但是 JSON 格式作为独立的数据格式存在于多种编程语言中。 JSON…

    C 2023年5月22日
    00
  • 荣耀畅玩8c怎么关闭后台?荣耀畅玩8c关闭后台应用教程

    下面我来详细讲解“荣耀畅玩8c怎么关闭后台?荣耀畅玩8c关闭后台应用教程”。 前言 荣耀畅玩8c 是一款性价比很高的手机,但是由于部分用户不了解如何关闭后台应用,在使用过程中会导致手机运行变慢、耗电等问题。因此,本文将详细介绍关闭荣耀畅玩8c 后台应用的方法。 步骤 方法一:手动清理后台应用 打开手机界面,找到 物理按键 或者 导航栏 。 双击 物理按键 或…

    C 2023年5月23日
    00
  • 使用C语言如何输出逆序数

    想要在C语言中输出逆序数,我们可以使用一个循环结构和一些操作来实现。下面是使用C语言输出逆序数的完整攻略: 1. 按位取数 我们首先需要确定待逆序的数是多少,可以从用户输入中获取或者直接写入代码中。假设我们要逆序的数字是 $num$。 接下来我们要按位去取 $num$ 中的数字,可以通过使用取模和整数除法来实现。 通过依次取出 $num$ 的个位数、十位数、…

    C 2023年5月23日
    00
  • win10下VSCode+CMake+Clang+GCC环境搭建教程图解

    以下是“win10下VSCode+CMake+Clang+GCC环境搭建教程图解”的完整攻略。 简介 Visual Studio Code是一款非常流行的开源跨平台代码编辑器。而CMake、Clang和GCC则是C/C++开发中用到的重要工具和库,它们能够优化代码编译、调试等方面的问题。在win10系统下配置VS Code+CMake+Clang+GCC环境…

    C 2023年5月23日
    00
  • 用C++实现队列的程序代码

    实现队列的程序代码主要涉及以下内容:数据结构、队列的操作、C++语法等。下面我们一步步来进行讲解。 数据结构 队列可以看成是一种特殊的线性表,它具有先进先出(FIFO)的特点,即先进队列的元素将先输出,后进队列的元素将后输出。 队列通常包含以下几个基本操作:入队、出队、判空和求队列长度等。入队就是将新元素插入到队列的末尾,出队就是将队头元素删除并返回,判空就…

    C 2023年5月23日
    00
  • Android编程之json解析实例详解

    我将为你介绍一下 “Android编程之json解析实例详解” 的完整攻略。 1. 什么是Json? JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它基于JavaScript代码语法,但是与之无关。在Android编程中,Json数据常常被用来传递数据。 2. Json的基本格式 下面是一个Json的基本格式: …

    C 2023年5月23日
    00
  • Windows Server 2019 MySQL数据库的安装与配置理论+远程连接篇

    Windows Server 2019 MySQL数据库的安装与配置理论+远程连接篇 1. 安装MySQL数据库 1.1 下载MySQL安装程序 首先需要到MySQL的官网(https://www.mysql.com/)上下载对应版本的安装程序。选择Windows版本的下载链接,并选择适合自己系统的版本进行下载:MySQL Community Server。…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部