<form id="dlljd"></form>
        <address id="dlljd"><address id="dlljd"><listing id="dlljd"></listing></address></address>

        <em id="dlljd"><form id="dlljd"></form></em>

          <address id="dlljd"></address>
            <noframes id="dlljd">

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

              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 中文字幕在线观看亚洲日韩