一区二区三区电影_国产伦精品一区二区三区视频免费_亚洲欧美国产精品va在线观看_国产精品一二三四

聯系我們 - 廣告服務 - 聯系電話:
您的當前位置: > 關注 > > 正文

java中的心跳包是如何發送的?心跳檢測實現2.1-速讀

來源:CSDN 時間:2023-04-24 08:22:32

1. 心跳機制簡介

在長連接下,可能很長一段時間都沒有數據往來。理論上說,這個連接是一直保持連接的,但是實際情況中,如果中間節點出現什么故障是難以知道的。更致命的是,有的節點(防火墻)會自動把一定時間之內沒有數據交互的連接給斷掉。這個時候,就可以使用心跳包,來維持長連接以及保活

心跳機制就是每隔幾分鐘發送一個固定信息給服務端,服務端收到后回復一個固定信息如果服務端幾分鐘內沒有收到客戶端信息則視客戶端斷開。發包方可以是客戶也可以是服務端,具體看哪邊實現更方便合理


(資料圖)

心跳包的發送通常有以下兩種技術:

1、應用層自已實現的心跳包:

由應用程序自己發送心跳包來檢測連接是否正常,服務器每隔一定時間向客戶端發送一個短小的數據包,然后啟動一個線程,在線程中不斷檢測客戶端的回應, 如果在一定時間內沒有收到客戶端的回應,即認為客戶端已經掉線;同樣,如果客戶端在一定時間內沒有收到服務器的心跳包,則認為連接不可用

2、使用SO_KEEPALIVE套接字選項:

在TCP的機制里面,本身是存在有心跳包的機制的,也就是TCP的選項. 不論是服務端還是客戶端,一方開啟KeepAlive功能后,就會自動在規定時間內向對方發送心跳包, 而另一方在收到心跳包后就會自動回復,以告訴對方我仍然在線

2. 心跳檢測實現

2.1 setsockopt函數介紹

函數功能:設置與某個套接字關聯的選項。選項可能存在于多層協議中,它們總會出現在最上面的套接字層。當操作套接字選項時,選項位于的層和選項的名稱必須給出。為了操作套接字層的選項,應該將層的值指定為SOL_SOCKET。為了操作其它層的選項,控制選項的合適協議號必須給出。例如,為了表示一個選項由TCP協議解析,層應該設定為協議號TCP

函數原型:int setsockopt(int sock, //將要被設置選項的套接字int level, //選項所在的協議層int optname, //需要訪問的選項名const void *optval, //指向包含新選項值得緩沖socklen_t optlen)//現選項的長度返 回 值:成功返回0;失敗返回-1

參數(level)詳細說明:level是指定控制套接字的層次,可以取如下三種值

SOL_SOCKET:通用套接字選項

選項名稱(optname)

說明

數據類型========================================================================SO_BROADCAST

允許發送廣播數據

intSO_DEBUG

允許調試

intSO_DONTROUTE

不查找

intSO_ERROR

獲得套接字錯誤

intSO_KEEPALIVE

保持連接

intSO_LINGER

延遲關閉連接

struct lingerSO_OOBINLINE

帶外數據放入正常數據流

intSO_RCVBUF

接收緩沖區大小

intSO_SNDBUF

發送緩沖區大小

intSO_RCVLOWAT

接收緩沖區下限

intSO_SNDLOWAT

發送緩沖區下限

intSO_RCVTIMEO

接收超時

struct timevalSO_SNDTIMEO

發送超時

struct timevalSO_REUSERADDR

允許重用本地地址和端口

intSO_TYPE

獲得套接字類型

intSO_BSDCOMPAT

與BSD系統兼容

int========================================================================

IPPROTO_IP:IP選項

選項名稱(optname)

說明

數據類型========================================================================IP_HDRINCL

在數據包中包含IP首部

intIP_OPTINOS

IP首部選項

intIP_TOS

類型IP_TTL

生存時間

int========================================================================

IPPROTO_TCP:TCP選項

選項名稱(optname)

說明

數據類型========================================================================TCP_MAXSEG

TCP最大數據段的大小

intTCP_NODELAY

不使用Nagle算法

int========================================================================

2.2 心跳機制的實現

該實例實現的功能:在TCP客戶端代碼中加入心跳機制,使服務端在斷網重連(與客戶端)后,能自動保持連接

參考Socket API編程優化一文,在該文的工程源碼基礎上進行修改keepalive宏開關:將opt.h文件中的LWIP_TCP_KEEPALIVE宏定義開啟

/** * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set * in seconds. (does not require sockets.c, and will affect tcp.c) */#if !defined LWIP_TCP_KEEPALIVE || defined __DOXYGEN__#define LWIP_TCP_KEEPALIVE              1#endif

setsockopt參數含義:sockets.h文件中可以看到如下setsockopt參數的設置

#define SO_KEEPALIVE   0x0008  /* 保持連接 */  #define TCP_KEEPIDLE   0x03    /* 發送心跳空閑周期 S*/ #define TCP_KEEPINTVL  0x04    /* 發送心跳間隔 S */  #define TCP_KEEPCNT    0x05    /* 心跳重發次數 */

在工程中創建tcp_keepalive.c和對應的頭文件

#include "socket_tcp_server.h"#include "tcp_keepalive.h"#include "socket_wrap.h"#include "ctype.h"#include "FreeRTOS.h"#include "task.h"static char ReadBuff[BUFF_SIZE];void vTcpKeepaliveTask(void){  int cfd, n, i, ret;  struct sockaddr_in server_addr;  int so_keepalive_val = 1;  int tcp_keepalive_idle = 3;  int tcp_keepalive_intvl = 3;  int tcp_keepalive_cnt = 3;  int tcp_nodelay = 1;again:  //創建socket  cfd = Socket(AF_INET, SOCK_STREAM, 0);  //使能socket層的心跳檢測  setsockopt(cfd, SOL_SOCKET, SO_KEEPALIVE, &so_keepalive_val, sizeof(int));  server_addr.sin_family = AF_INET;  server_addr.sin_port = htons(SERVER_PORT);  server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);  /*連接到服務器(connect是一個阻塞接口,內部要完成TCP的三次握手;    里面有超時機制,所以需要等一段時間,才能重新連接到服務器)*/  ret = Connect(cfd, (struct sockaddr*)&server_addr, sizeof(server_addr));  if(ret < 0){//100ms去連接一次服務器vTaskDelay(100);goto again;  }  //配置心跳檢測參數   默認參數時間很長  setsockopt(cfd, IPPROTO_TCP, TCP_KEEPIDLE, &tcp_keepalive_idle, sizeof(int));  setsockopt(cfd, IPPROTO_TCP, TCP_KEEPINTVL, &tcp_keepalive_intvl, sizeof(int));  setsockopt(cfd, IPPROTO_TCP, TCP_KEEPCNT, &tcp_keepalive_cnt, sizeof(int));  setsockopt(cfd, IPPROTO_TCP, TCP_NODELAY, &tcp_nodelay, sizeof(int));  printf("server is connect ok\r\n");  while(1){//等待服務器發送數據n = Read(cfd, ReadBuff, BUFF_SIZE);if(n <= 0){  goto again;}//進行大小寫轉換for(i = 0; i < n; i++){      ReadBuff[i] = toupper(ReadBuff[i]);}//寫回服務器n = Write(cfd, ReadBuff, n);if(n <= 0){  goto again;}  }}

在freertos.c文件中的默認任務里面添加代碼

void StartDefaultTask(void const * argument){  /* init code for LWIP */  MX_LWIP_Init();  /* USER CODE BEGIN StartDefaultTask */  printf("TCP keepalive test!\r\n");  /* Infinite loop */  for(;;){    vTcpKeepaliveTask();osDelay(100);  }  /* USER CODE END StartDefaultTask */}

責任編輯:

標簽: 客戶端

相關推薦:

精彩放送:

新聞聚焦
Top 主站蜘蛛池模板: 乌拉特后旗| 穆棱市| 射阳县| 庐江县| 永安市| 中卫市| 罗定市| 弋阳县| 平乐县| 甘谷县| 剑川县| 湘潭县| 乌拉特中旗| 都兰县| 水富县| 凤庆县| 阿勒泰市| 安康市| 绍兴县| 搜索| 遂平县| 新竹县| 林甸县| 来凤县| 湖南省| 鹤山市| 太白县| 济源市| 张北县| 武宣县| 安福县| 深州市| 读书| 南丰县| 基隆市| 灌阳县| 河池市| 缙云县| 谢通门县| 长治市| 河东区|