色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

為什么要使用 TCP keepalive

科技綠洲 ? 來源:Linux開發架構之路 ? 作者:Linux開發架構之路 ? 2023-11-13 11:28 ? 次閱讀

為了理解 TCP keepalive的作用。我們需要清楚,當TCP的Peer A ,Peer B 兩端建立了連接之后,如果一端突然拔掉網線或拔掉電源時,怎么檢測到拔掉網線或者拔掉電源、鏈路不通?原因是在需要長連接的網絡通信程序中,經常需要心跳檢測機制,來實現檢測對方是否在線或者維持網絡連接的需要。

什么是 TCP ?;??

當你建立一個 TCP 連接時,你關聯了一組定時器。其中一些計時器處理?;钸^程。當?;钣嫊r器達到零時,向對等方發送一個?;钐綔y數據包,其中沒有數據并且 ACK 標志打開。

由于 TCP/IP 規范,可以這樣做,作為一種重復的 ACK,并且遠程端點將沒有參數,因為 TCP 是面向流的協議。另一方面,將收到來自遠程主機的回復,沒有數據和ACK 集。

如果收到對 keepalive 探測的回復,則可以斷言連接仍在運行。事實上,TCP 允許處理流,而不是數據包,因此零長度數據包對用戶程序沒有危險。

此過程很有用,因為如果其他對等方失去連接(例如通過重新啟動),即使沒有流量,也會注意到連接已斷開。如果對等方未回復 keepalive 探測,可以斷言連接不能被視為有效,然后采取正確的操作。

為什么要使用 TCP keepalive?

1、檢查死節點 2、 防止因網絡不活動而斷開連接

檢查死節點

想一想 Peer A 和 Peer B 之間的簡單 TCP 連接:初始的三次握手,從 A 到 B 的一個 SYN 段,從 B 到 A 的 SYN/ACK,以及從 A 到 B 的最終 ACK。

圖片

此時,我們處于穩定狀態:連接已建立,現在我們通常會等待有人通過通道發送數據。

那么問題來了:從 B 上拔下電源,它會立即斷電,而不會通過網絡發送任何信息來通知 A 連接將斷開。

從它的角度來看,A 已準備好接收數據,并且不知道 B 已經崩潰。現在恢復B的電源,等待系統重啟。A 和 B 現在又回來了,但是當 A 知道與 B 仍然處于活動狀態的連接時,B 不知道。當 A 嘗試通過死連接向 B 發送數據時,情況自行解決,B 回復 RST 數據包,導致 A 最終關閉連接。

_____                                                     _____
   |     |                                                   |     |
   |  A  |                                                   |  B  |
   |_____|                                                   |_____|
      ^                                                         ^
      |--- >--- >--- >-------------- SYN -------------- >--- >--- >---|
      |---< ---< ---< ------------ SYN/ACK ------------< ---< ---< ---|
      |--- >--- >--- >-------------- ACK -------------- >--- >--- >---|
      |                                                         |
      |                                       system crash --- > X
      |
      |                                     system restart --- > ^
      |                                                         |
      |--- >--- >--- >-------------- PSH -------------- >--- >--- >---|
      |---< ---< ---< -------------- RST --------------< ---< ---< ---|
      |                                                         |

Keepalive 可以告訴您何時無法訪問另一個對等點,而不會出現誤報的風險。

防止因網絡不活動而斷開連接

keepalive 的另一個有用目標是防止不活動斷開通道。當你在 NAT 代理或防火墻后面時,無緣無故斷開連接是一個非常常見的問題。這種行為是由代理和防火墻中實現的連接跟蹤過程引起的,它們跟蹤通過它們的所有連接。

它們跟蹤通過它們的所有連接。由于這些機器的物理限制,它們只能在內存中保留有限數量的連接。最常見和合乎邏輯的策略是保持最新的連接并首先丟棄舊的和不活動的連接。

_____           _____                                     _____
   |     |         |     |                                   |     |
   |  A  |         | NAT |                                   |  B  |
   |_____|         |_____|                                   |_____|
      ^               ^                                         ^
      |--- >--- >--- >---|----------- SYN ------------- >--- >--- >---|
      |---< ---< ---< ---|--------- SYN/ACK -----------< ---< ---< ---|
      |--- >--- >--- >---|----------- ACK ------------- >--- >--- >---|
      |               |                                         |
      |               | < --- connection deleted from table      |
      |               |                                         |
      |--- >- PSH - >---| < --- invalid connection                 |
      |               |                                         |

Linux下使用TCP keepalive

Linux 內置了對 keepalive 的支持。涉及 keepalive 的過程使用三個用戶驅動的變量,可以使用 cat 查看參數值。

圖片

前兩個參數以秒表示,最后一個是純數字。這意味著keepalive 例程在發送第一個keepalive 探測之前等待兩個小時(7200 秒),然后每75 秒重新發送一次。如果連續9次沒有收到 ACK 響應,則連接被標記為斷開。

修改這個值很簡單,可以這樣修改:

echo 7000 > /proc/sys/net/ipv4/tcp_keepalive_time echo 40 > /proc/sys/net/ipv4/tcp_keepalive_intvl echo 10 > /proc/sys/net/ipv4/tcp_keepalive_probes

還有另一種訪問內核變量的方法,使用 sysctl 命令

圖片

setsockopt 、getsockopt 函數調用

在 Linux 操作系統中,我們可以通過代碼啟用一個 socket 的心跳檢測,為特定套接字啟用 keepalive 所需要做的就是在套接字本身上設置特定的套接字選項。函數原型如下:

int getsockopt(int sockfd, int level, int optname,
                      void *optval, socklen_t *optlen);

int setsockopt(int sockfd, int level, int optname,
                      const void *optval, socklen_t optlen);

圖片

第一個參數是socket;第二個必須是 SOL_SOCKET,第三個必須是 SO_KEEPALIVE。第四個參數必須是布爾整數值,表示我們要啟用該選項,而最后一個是之前傳遞的值的大小。

在編寫應用程序時,還可以為 keepalive 設置其他三個套接字選項。它們都使用 SOL_TCP 級別而不是 SOL_SOCKET,并且它們僅針對當前套接字覆蓋系統范圍的變量。如果不先寫入就讀取,將返回當前系統范圍的參數。

TCP_KEEPCNT:覆蓋 tcp_keepalive_probes
TCP_KEEPIDLE:覆蓋 tcp_keepalive_time
TCP_KEEPINTVL:覆蓋 tcp_keepalive_intvl

TCP keepalive 代碼實現

在寫TCP keepalive 服務程序時,除了要處理SIGPIPE外,還要有客戶端連接檢測機制,用于及時發現崩潰的客戶端連接。我們使用TCP的 keepalive 機制方式。

tcp_keepalive_client:

int main(int argc, char *argv[])
{
 kat_arg0 = basename(argv[0]);
 bzero(&cp, sizeof (cp));
 cp.cp_keepalive = 1;
 cp.cp_keepidle = -1;
 cp.cp_keepcnt = -1;
 cp.cp_keepintvl = -1;

 while ((c = getopt(argc, argv, ":c:d:i:")) != -1) {
  switch (c) {
  case 'c':
   cp.cp_keepcnt = parse_positive_int_option(
       optopt, optarg);
   break;

  case 'd':
   cp.cp_keepidle = parse_positive_int_option(
       optopt, optarg);
   break;

  case 'i':
   cp.cp_keepintvl = parse_positive_int_option(
       optopt, optarg);
   break;

  case ':':
   warnx("option requires an argument: -%c", optopt);
   usage();
   break;

  case '?':
   warnx("unrecognized option: -%c", optopt);
   usage();
   break;
  }
 }

 if (optind > argc - 1) {
  warnx("missing required arguments");
  usage();
 }

 ipport = argv[optind++];
 if (parse_ip4port(ipport, &cp.cp_ip) == -1) {
  warnx("invalid IP/port: "%s"", ipport);
  usage();
 }

 (void) fprintf(stderr, "going connect to: %s port %dn",
     inet_ntoa(cp.cp_ip.sin_addr), ntohs(cp.cp_ip.sin_port));
 (void) fprintf(stderr, "set SO_KEEPALIVE  = %dn", cp.cp_keepalive);
 (void) fprintf(stderr, "set TCP_KEEPIDLE  = %dn", cp.cp_keepidle);
 (void) fprintf(stderr, "set TCP_KEEPCNT   = %dn", cp.cp_keepcnt);
 (void) fprintf(stderr, "set TCP_KEEPINTVL = %dn", cp.cp_keepintvl);
 rv = connectandwait(&cp);
 return (rv == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}

tcp_keepalive_server:

int main(int argc, char *argv[] )
{

   /* 創建套接字 */
   if((listen_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
      perror("socket()");
      exit(EXIT_FAILURE);
   }

   /* 檢查 keepalive 選項的狀態  */
   if(getsockopt(listen_sock, SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen) < 0) {
      perror("getsockopt()");
      close(listen_sock);
      exit(EXIT_FAILURE);
   }
   printf("SO_KEEPALIVE default is %sn", (optval ? "ON" : "OFF"));

   /* 將選項設置為活動  */
   optval = 1;
   optlen = sizeof(optval);

   if(setsockopt(listen_sock, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
      perror("setsockopt()");
      close(listen_sock);
      exit(EXIT_FAILURE);
   }
   printf("SO_KEEPALIVE set on socketn");

   /* 再次檢查狀態  */
   if(getsockopt(listen_sock, IPPROTO_TCP, TCP_KEEPIDLE, &optval, &optlen) < 0) {
      perror("getsockopt()");
      close(listen_sock);
      exit(EXIT_FAILURE);
   }
   printf("TCP_KEEPIDLE is %dn", optval );
      /* 再次檢查狀態  */
   if(getsockopt(listen_sock, IPPROTO_TCP, TCP_KEEPCNT, &optval, &optlen) < 0) {
      perror("getsockopt()");
      close(listen_sock);
      exit(EXIT_FAILURE);
   }
   printf("TCP_KEEPCNT is %dn", optval);
      /* 再次檢查狀態  */
   if(getsockopt(listen_sock, IPPROTO_TCP, TCP_KEEPINTVL, &optval, &optlen) < 0) {
      perror("getsockopt()");
      close(listen_sock);
      exit(EXIT_FAILURE);
   }
   printf("TCP_KEEPINTVL is %dn", optval );
  /* 初始化套接字結構 */
   bzero((char *) &serv_addr, sizeof(serv_addr));
   int portno = atoi(argv[1]);
   serv_addr.sin_family = AF_INET;
   serv_addr.sin_addr.s_addr = INADDR_ANY;
   serv_addr.sin_port = htons(portno);

  ...
 }

圖片

圖片

程序創建一個 TCP 套接字并將 SO_KEEPALIVE 套接字選項設置為 1。如果指定了“-c”、“-d”和“-i”選項中的任何一個,則設置 TCP_KEEPCNT、TCP_KEEPIDLE 和 TCP_KEEPINTVL 套接字選項 在相應選項參數的套接字上。

通過測試程序,我們可以使用tcpdump、或者tshark是命令行抓包工具,來分析KeepAlive。

tshark -nn -i lo port 5050 tcpdump -nn -i lo port 5050

圖片

tcpdump -nn -i lo port 5050

圖片

整個keepalive過程很簡單,就是client給server發送一個包,server返回給用戶一個包。注意包內沒有數據,只有ACK標識 被打開。

ps -aux | grep tcp_keepalive

圖片

總結

keepalive 是一個設備向另一個設備發送的消息,用于檢查兩者之間的鏈路是否正在運行,或防止鏈路中斷。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 電源
    +關注

    關注

    184

    文章

    17706

    瀏覽量

    249995
  • TCP
    TCP
    +關注

    關注

    8

    文章

    1353

    瀏覽量

    79058
  • 程序
    +關注

    關注

    117

    文章

    3785

    瀏覽量

    81009
  • 網絡通信
    +關注

    關注

    4

    文章

    797

    瀏覽量

    29797
收藏 人收藏

    評論

    相關推薦

    ESP32-S3使用tcp_server例程,將網絡數據和串口數據透傳延遲過高怎么解決?

    ;, errno);break;}tcp_sock = sock;// Set tcp keepalive optionsetsockopt(sock, SOL_SOCKET, SO_KEEP
    發表于 06-06 06:06

    ESP8266 TCP保持活動狀態功能似乎不起作用,為什么?

    。 當我為TCP客戶端設置保持活動狀態參數時: ... client_fd= socket(); ... int keepAlive = 1; //enable keepalive int
    發表于 07-12 08:00

    如何使用espconn_set_keepalive?

    我想建立一個 TCP 連接,該連接在第一次數據發送后不會關閉,我閱讀了有關 espconn_set_保持活著 函數的信息,該函數將心跳發送到服務器,因此它不會斷開連接(如果我理解正確的話)。但是我
    發表于 07-12 15:10

    使用esp_iot_sdk_v1.0.1_15_04_24時keepalive無效的原因?

    我的keepalive功能一直都正常,替換成新的esp_iot_sdk_v1.0.1_15_04_24 SDK后,keepalive就沒有了,我的代碼未變動 nKeepaliveParam
    發表于 07-12 09:28

    請問ESP8266 SDK可以添加KeepAlive獲取狀態接口嗎?

    我在我的 TCP 套接字中啟用了 keepalive,它可以發送和接收 keepalive packt 將本地服務器,但我突然關閉了我的本地服務器以測試 esp8266 在這種情況下可以注意到
    發表于 07-12 09:03

    求助,關于AT+CIPSTART指令keepalive功能的問題求解

    都沒有任何響應,所以也不知道具體是多久斷開。 所以嘗試用AT+CIPSTART指令設置Keepalive功能來保持服務器連接,結果發現我設置成60秒,到了60秒就返回一個CLOSE。 一開始我以為是
    發表于 07-16 07:47

    LWIP的keepalive功能TCP長時間不再發送數據就會斷開連接

    把LWIP中的keepalive功能打開之后,如果協議棧檢測到TCP長時間不再發送數據就會把連接斷開。如果我在網絡正常通信的情況下突然拔掉網線,等到協議棧把TCP連接斷開后,再插上網線,但是卻不能重新連接之前的
    發表于 04-06 04:36

    tcp ip協議_什么是tcp ip協議

    什么是tcp ip協議,tcp ip協議詳解,深刻講述了tcp ip協議的概念,tcp ip協議層次等知識
    發表于 05-14 16:29 ?6032次閱讀
    <b class='flag-5'>tcp</b> ip協議_什么是<b class='flag-5'>tcp</b> ip協議

    TCP實現:TCP輸出

    學習TCP-IP的很好的書。TCP-IP詳解卷3。
    發表于 05-09 14:33 ?0次下載

    TCP實現:TCP概要

    學習TCP-IP的很好的書。TCP-IP詳解卷3。
    發表于 05-09 16:07 ?0次下載

    TCP實現:TCP函數

    學習TCP-IP的很好的書。TCP-IP詳解卷3。
    發表于 05-09 16:07 ?0次下載

    TCP實現:TCP輸入

    學習TCP-IP的很好的書。TCP-IP詳解卷3。
    發表于 05-09 16:07 ?0次下載

    CUBE配置STM32H750、Lan8720、FreeRTOS、lwip、掉線重連、KeepAlive移植

    重連實現2.2 TCP保活(keepalive)設定3. 代碼實現3.1 Freertos.c3.2 tcpe
    發表于 12-27 18:48 ?94次下載
    CUBE配置STM32H750、Lan8720、FreeRTOS、lwip、掉線重連、<b class='flag-5'>KeepAlive</b>移植

    TCP keepalive機制具體是怎么樣的

    今天,聊一個有趣的問題:拔掉網線幾秒,再插回去,原本的 TCP 連接還存在嗎?
    的頭像 發表于 03-11 16:50 ?2807次閱讀

    Keepalive基礎知識

    Keepalive 1 keepalived介紹 ? 官網:http://keepalived.org/ ? 功能: 基于vrrp協議完成地址流動 為vip地址所在的節點生成ipvs規則(在配置文件
    的頭像 發表于 12-19 09:57 ?57次閱讀
    <b class='flag-5'>Keepalive</b>基礎知識
    主站蜘蛛池模板: 亚洲AVAV天堂AV在线网爱情| 中文字幕在线观看亚洲日韩| 精品久久久久久久国产潘金莲| 最近中文字幕在线中文高清版 | 免费国产在线观看| 调教玩弄奶头乳夹开乳震动器| 亚洲欧美偷拍视频一区| 肉动漫h黄动漫日本免费观看| 寂寞夜晚看免费视频| 丰满的大白屁股ass| 中文字幕精品视频在线| 乡村教师电影版| 欧美性xxxxxx爱| 久久精品国产色蜜蜜麻豆国语版| 国产99视频精品免费播放| 91热久久免费频精品99欧美| 亚洲国产日韩欧美在线a乱码 | FREECHINESE东北群交| 羽月希被黑人吃奶dasd585| 神马伦理2019影院不卡片| 欧美精品做人一级爱免费| 久久婷婷色香五月综合激情 | 青草久久影院| 蜜桃传媒在线观看| 久久国产精品久久国产精品| 国产喷水1区2区3区咪咪爱AV| 成 人 网 站毛片| 99热这里只有精品视频2| 13小箩利洗澡无码视频APP| 野花韩国高清完整版在线观看5| 午夜免费国产体验区免费的| 色-情-伦-理一区二区三区| 欧美一区二区视频在线观看| 男女啪啪抽搐呻吟高潮动态图| 老阿姨儿子一二三区| 久久成人免费观看全部免费| 国语自产拍在线视频普通话| 国产乱码精品AAAAAAAA| 国产精品嫩草99AV在线| 国产精品久久久久AV麻豆| 国产国拍精品AV在线观看|