ZBLOG

如果send失败需要重新建立tcp_socket

如果 send 函数调用失败且需要重新建立 TCP socket,可以在 send 失败后进行适当的处理。以下是一个示例,展示了如何在发送数据时检查错误,并在发生特定错误时重新建立 TCP socket。

假设我们已经有一个创建和连接 TCP socket 的函数,以及发送心跳和 CPU 使用情况的代码。我们可以添加一个重试机制来处理 send 失败的情况。

下面是更新后的代码示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/timerfd.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>  
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define SERVER_PORT 12345 // 假设服务器端口为 12345
#define SERVER_IP "127.0.0.1" // 假设服务器 IP 为本地地址

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

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr);

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

    return sockfd;
}

void record_cpu_usage() {
   static long prev_idle = 0;
   static long prev_total = 0;

   FILE *fp = fopen("/proc/stat", "r");
   if (!fp) {
       perror("fopen");
       return;
   }

   char buffer[256];
   fgets(buffer, sizeof(buffer), fp);

   long user, nice, system, idle, iowait, irq, softirq;
   sscanf(buffer,"cpu %ld %ld %ld %ld %ld %ld %ld",&user,&nice,&system,&idle,&iowait,&irq,&softirq);

   long total = user + nice + system + idle + iowait + irq + softirq;

   long diff_idle = idle - prev_idle;
   long diff_total = total - prev_total;

   if (diff_total > 0) {
       double cpu_usage = (double)(diff_total - diff_idle) / diff_total * 100.0;
       printf("CPU Usage: %.2f%%\n", cpu_usage);
   }

   prev_idle = idle; 
   prev_total = total;

   fclose(fp);
}

void heartbeat(int sockfd) {
    const char *message = "Heartbeat: System is alive!\n";
    
    ssize_t bytes_sent = send(sockfd, message, strlen(message), 0);
    
    if (bytes_sent < 0) {
        perror("send failed");
        
        // 如果发送失败,尝试重新建立TCP连接
        close(sockfd); // 首先关闭旧的socket
        sockfd = create_tcp_socket(); // 创建新的socket

        if (sockfd >= 0) { 
            printf("Reconnected to the server.\n");
            // 可以考虑重发之前的数据(如心跳),这里仅作为示例。
            send(sockfd,message ,strlen(message), 0);
        } else {
            fprintf(stderr,"Failed to reconnect to the server.\n");
        }
        
     } else{
         printf("%s", message); // 打印已成功发送的消息
     }
}

void monitor_cpu_and_send_heartbeat(int tfd) {
    uint64_t expirations;
    int heartbeat_counter = 0;

    int sockfd = create_tcp_socket(); // 建立初始TCP连接
    if (sockfd < 0) return; // 如果连接失败则返回

    while (1) {
        fd_set readfds;
        FD_ZERO(&readfds);
        FD_SET(tfd ,&readfds);

        select(tfd +1 , &readfds , NULL ,NULL,NULL );

        if (FD_ISSET(tfd ,&readfds)){
            read(tfd , &expirations,sizeof(expirations));

            record_cpu_usage();
            
            heartbeat_counter++;
            if (heartbeat_counter >=30){ 
                heartbeat(sockfd); 
                heartbeat_counter=0; 
             }
         }
     }

     close(sockfd); // 不要忘记在退出前关闭socket
}

int main() {
   
 int tfd= timerfd_create(CLOCK_MONOTONIC ,0);
 if(tfd ==-1){
      perror("timerfd_create");
      exit(EXIT_FAILURE);
 }
 
 struct itimerspec new_value ;
 new_value.it_value.tv_sec=1; 
 new_value.it_value.tv_nsec=0; 
 new_value.it_interval.tv_sec=1; 
 new_value.it_interval.tv_nsec=0; 

 timerfd_settime(tfd ,0 ,&new_value,NULL);

 monitor_cpu_and_send_heartbeat(tfd);

 close(tfd );
 return EXIT_SUCCESS;
}

更新说明:

  • 新增了 create_tcp_socket() 函数,该函数用于创建并连接到指定服务器的 TCP socket。
  • heartbeat() 函数中,如果 send() 调用失败,关闭旧的 socket,并调用 create_tcp_socket() 尝试重新建立连接。如果成功建立新连接,则可以选择重发之前的信息。
  • 在主循环中维护一个有效的 socket,以确保每次心跳都能通过有效的 TCP 链接发送。

这种实现方式能够确保程序在网络故障情况下依然保持稳定,通过重连机制恢复与服务端的通信。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=6991

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?