如何在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日

相关文章

  • C语言 strcmp()函数

    C语言 strcmp()函数使用攻略 介绍 strcmp()函数是C语言标准库中的一员,是string.h头文件中的字符串比较函数,用于比较两个字符串是否相等。该函数会依次比较两个字符串相应位置的字符的ASCII码大小关系,直到出现不同字符或遇到字符串结束符’\0’。如果两个字符串完全相同,则该函数返回0;如果两个字符串在某个位置上出现不同,则该函数返回第一…

    C 2023年5月9日
    00
  • VSCode搭建C/C++编译环境的详细教程

    让我们来详细讲解一下“VSCode搭建C/C++编译环境的详细教程”,具体步骤如下: 1. 安装VSCode 下载并安装Visual Studio Code: https://code.visualstudio.com/ 2. 安装C/C++插件 在VSCode中点击菜单栏的“扩展”(Extensions)按钮,在搜索框中输入“C/C++”,找到官方提供的插…

    C 2023年5月23日
    00
  • 16种C语言编译警告(Warning)类型的解决方法

    16种C语言编译警告(Warning)类型的解决方法 编写代码时,编译器经常会发出警告。这些警告不一定表示代码有错误,但警告应该受到注意并解决。本文将介绍C语言编译警告的16种类型以及如何解决它们。 1. 程序参数不匹配 int main() { printf("hello World\n"); return 0; } 警告信息:warn…

    C 2023年5月23日
    00
  • C语言围圈报数题目代码实现

    我先来介绍一下 “C语言围圈报数题目代码实现” 是什么: 这是一道经典的数学题目,题目有三个人围成一圈,他们报数,规定报到第三个人的时候要翻过去,也就是从头开始,如此循环,直到只剩下最后一个人。现在我们需要用C语言实现这个过程。 下面是该算法的完整实现,以及代码解析: 思路分析 1.将所有人简化为一个数组,数组的下标表示的是人的编号。2.从第k个人开始循环报…

    C 2023年5月24日
    00
  • C语言实现歌手大奖赛计分程序

    C语言实现歌手大奖赛计分程序 程序实现功能 本程序主要实现歌手大奖赛计分功能,包括对选手的评分以及最终的排名输出。 实现思路 程序主要分为以下几个步骤进行实现: 获取选手总数 获取评委人数 获取选手分数 对选手的得分进行排序 最终输出选手排名 具体实现步骤 获取选手总数以及评委人数 可以使用scanf函数来获取用户输入的选手总数以及评委人数。 int sin…

    C 2023年5月23日
    00
  • C++实现宿舍管理查询系统

    C++实现宿舍管理查询系统攻略 1. 系统介绍 C++实现宿舍管理查询系统是一款基于控制台界面的宿舍管理查询应用。该系统主要用于方便宿舍管理员进行学生入住管理和住宿情况查询。系统功能包括:学生信息录入、住宿信息录入、学生信息查询、住宿信息查询、学生信息删除等。 2. 开发环境 操作系统:Windows 10 编程语言:C++ 集成开发环境:Visual St…

    C 2023年5月23日
    00
  • Win7系统应用程序正常初始化失败提示0xc0000135解决方法

    Win7系统应用程序正常初始化失败提示0xc0000135解决方法 问题描述 在Win7系统中,当你尝试打开某些应用程序时,有可能会出现应用程序正常初始化失败提示0xc0000135的错误信息。这个问题可能会影响到你的工作或者娱乐,因此我们需要找到解决方法。 原因分析 这个问题通常是由于系统缺少某些依赖库或者依赖库损坏造成的,使得应用程序无法正常初始化。这个…

    C 2023年5月24日
    00
  • C语言实现井字棋(三子棋)

    C语言实现井字棋(三子棋)攻略 概述 井字棋(三子棋)是一种比较简单的两人游戏,可以用来练习C语言编程基础。本攻略将介绍如何使用C语言实现井字棋(三子棋)游戏。 准备工作 在开始编写代码之前,需要先安装C语言编译器。这里我们推荐使用Dev-C++,因为它是一款免费、轻量级、易用的C语言编译器。安装完成后,打开Dev-C++,新建一个C源代码文件,即可开始编写…

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