ZBLOG

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

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

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

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

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/timerfd.h>
  5. #include <unistd.h>
  6. #include <time.h>
  7. #include <fcntl.h>
  8. #include <errno.h>
  9. #include <sys/socket.h>
  10. #include <netinet/in.h>
  11. #define SERVER_PORT 12345 // 假设服务器端口为 12345
  12. #define SERVER_IP "127.0.0.1" // 假设服务器 IP 为本地地址
  13. int create_tcp_socket() {
  14. int sockfd = socket(AF_INET, SOCK_STREAM, 0);
  15. if (sockfd < 0) {
  16. perror("socket");
  17. return -1;
  18. }
  19. struct sockaddr_in server_addr;
  20. memset(&server_addr, 0, sizeof(server_addr));
  21. server_addr.sin_family = AF_INET;
  22. server_addr.sin_port = htons(SERVER_PORT);
  23. inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr);
  24. if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
  25. perror("connect");
  26. close(sockfd);
  27. return -1;
  28. }
  29. return sockfd;
  30. }
  31. void record_cpu_usage() {
  32. static long prev_idle = 0;
  33. static long prev_total = 0;
  34. FILE *fp = fopen("/proc/stat", "r");
  35. if (!fp) {
  36. perror("fopen");
  37. return;
  38. }
  39. char buffer[256];
  40. fgets(buffer, sizeof(buffer), fp);
  41. long user, nice, system, idle, iowait, irq, softirq;
  42. sscanf(buffer,"cpu %ld %ld %ld %ld %ld %ld %ld",&user,&nice,&system,&idle,&iowait,&irq,&softirq);
  43. long total = user + nice + system + idle + iowait + irq + softirq;
  44. long diff_idle = idle - prev_idle;
  45. long diff_total = total - prev_total;
  46. if (diff_total > 0) {
  47. double cpu_usage = (double)(diff_total - diff_idle) / diff_total * 100.0;
  48. printf("CPU Usage: %.2f%%\n", cpu_usage);
  49. }
  50. prev_idle = idle;
  51. prev_total = total;
  52. fclose(fp);
  53. }
  54. void heartbeat(int sockfd) {
  55. const char *message = "Heartbeat: System is alive!\n";
  56. ssize_t bytes_sent = send(sockfd, message, strlen(message), 0);
  57. if (bytes_sent < 0) {
  58. perror("send failed");
  59. // 如果发送失败,尝试重新建立TCP连接
  60. close(sockfd); // 首先关闭旧的socket
  61. sockfd = create_tcp_socket(); // 创建新的socket
  62. if (sockfd >= 0) {
  63. printf("Reconnected to the server.\n");
  64. // 可以考虑重发之前的数据(如心跳),这里仅作为示例。
  65. send(sockfd,message ,strlen(message), 0);
  66. } else {
  67. fprintf(stderr,"Failed to reconnect to the server.\n");
  68. }
  69. } else{
  70. printf("%s", message); // 打印已成功发送的消息
  71. }
  72. }
  73. void monitor_cpu_and_send_heartbeat(int tfd) {
  74. uint64_t expirations;
  75. int heartbeat_counter = 0;
  76. int sockfd = create_tcp_socket(); // 建立初始TCP连接
  77. if (sockfd < 0) return; // 如果连接失败则返回
  78. while (1) {
  79. fd_set readfds;
  80. FD_ZERO(&readfds);
  81. FD_SET(tfd ,&readfds);
  82. select(tfd +1 , &readfds , NULL ,NULL,NULL );
  83. if (FD_ISSET(tfd ,&readfds)){
  84. read(tfd , &expirations,sizeof(expirations));
  85. record_cpu_usage();
  86. heartbeat_counter++;
  87. if (heartbeat_counter >=30){
  88. heartbeat(sockfd);
  89. heartbeat_counter=0;
  90. }
  91. }
  92. }
  93. close(sockfd); // 不要忘记在退出前关闭socket
  94. }
  95. int main() {
  96. int tfd= timerfd_create(CLOCK_MONOTONIC ,0);
  97. if(tfd ==-1){
  98. perror("timerfd_create");
  99. exit(EXIT_FAILURE);
  100. }
  101. struct itimerspec new_value ;
  102. new_value.it_value.tv_sec=1;
  103. new_value.it_value.tv_nsec=0;
  104. new_value.it_interval.tv_sec=1;
  105. new_value.it_interval.tv_nsec=0;
  106. timerfd_settime(tfd ,0 ,&new_value,NULL);
  107. monitor_cpu_and_send_heartbeat(tfd);
  108. close(tfd );
  109. return EXIT_SUCCESS;
  110. }

更新说明:

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

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


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

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

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

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

联系我们

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

微信号:3007537140

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

关注我们
x

注册

已经有帐号?