日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

為什么要使用 TCP keepalive

科技綠洲 ? 來(lái)源:Linux開(kāi)發(fā)架構(gòu)之路 ? 作者:Linux開(kāi)發(fā)架構(gòu)之路 ? 2023-11-13 11:28 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

為了理解 TCP keepalive的作用。我們需要清楚,當(dāng)TCP的Peer A ,Peer B 兩端建立了連接之后,如果一端突然拔掉網(wǎng)線或拔掉電源時(shí),怎么檢測(cè)到拔掉網(wǎng)線或者拔掉電源、鏈路不通?原因是在需要長(zhǎng)連接的網(wǎng)絡(luò)通信程序中,經(jīng)常需要心跳檢測(cè)機(jī)制,來(lái)實(shí)現(xiàn)檢測(cè)對(duì)方是否在線或者維持網(wǎng)絡(luò)連接的需要。

什么是 TCP ?;睿?/p>

當(dāng)你建立一個(gè) TCP 連接時(shí),你關(guān)聯(lián)了一組定時(shí)器。其中一些計(jì)時(shí)器處理?;钸^(guò)程。當(dāng)?;钣?jì)時(shí)器達(dá)到零時(shí),向?qū)Φ确桨l(fā)送一個(gè)?;钐綔y(cè)數(shù)據(jù)包,其中沒(méi)有數(shù)據(jù)并且 ACK 標(biāo)志打開(kāi)。

由于 TCP/IP 規(guī)范,可以這樣做,作為一種重復(fù)的 ACK,并且遠(yuǎn)程端點(diǎn)將沒(méi)有參數(shù),因?yàn)?TCP 是面向流的協(xié)議。另一方面,將收到來(lái)自遠(yuǎn)程主機(jī)的回復(fù),沒(méi)有數(shù)據(jù)和ACK 集。

如果收到對(duì) keepalive 探測(cè)的回復(fù),則可以斷言連接仍在運(yùn)行。事實(shí)上,TCP 允許處理流,而不是數(shù)據(jù)包,因此零長(zhǎng)度數(shù)據(jù)包對(duì)用戶程序沒(méi)有危險(xiǎn)。

此過(guò)程很有用,因?yàn)槿绻渌麑?duì)等方失去連接(例如通過(guò)重新啟動(dòng)),即使沒(méi)有流量,也會(huì)注意到連接已斷開(kāi)。如果對(duì)等方未回復(fù) keepalive 探測(cè),可以斷言連接不能被視為有效,然后采取正確的操作。

為什么要使用 TCP keepalive?

1、檢查死節(jié)點(diǎn) 2、 防止因網(wǎng)絡(luò)不活動(dòng)而斷開(kāi)連接

檢查死節(jié)點(diǎn)

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

圖片

此時(shí),我們處于穩(wěn)定狀態(tài):連接已建立,現(xiàn)在我們通常會(huì)等待有人通過(guò)通道發(fā)送數(shù)據(jù)。

那么問(wèn)題來(lái)了:從 B 上拔下電源,它會(huì)立即斷電,而不會(huì)通過(guò)網(wǎng)絡(luò)發(fā)送任何信息來(lái)通知 A 連接將斷開(kāi)。

從它的角度來(lái)看,A 已準(zhǔn)備好接收數(shù)據(jù),并且不知道 B 已經(jīng)崩潰。現(xiàn)在恢復(fù)B的電源,等待系統(tǒng)重啟。A 和 B 現(xiàn)在又回來(lái)了,但是當(dāng) A 知道與 B 仍然處于活動(dòng)狀態(tài)的連接時(shí),B 不知道。當(dāng) A 嘗試通過(guò)死連接向 B 發(fā)送數(shù)據(jù)時(shí),情況自行解決,B 回復(fù) RST 數(shù)據(jù)包,導(dǎo)致 A 最終關(guān)閉連接。

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

Keepalive 可以告訴您何時(shí)無(wú)法訪問(wèn)另一個(gè)對(duì)等點(diǎn),而不會(huì)出現(xiàn)誤報(bào)的風(fēng)險(xiǎn)。

防止因網(wǎng)絡(luò)不活動(dòng)而斷開(kāi)連接

keepalive 的另一個(gè)有用目標(biāo)是防止不活動(dòng)斷開(kāi)通道。當(dāng)你在 NAT 代理或防火墻后面時(shí),無(wú)緣無(wú)故斷開(kāi)連接是一個(gè)非常常見(jiàn)的問(wèn)題。這種行為是由代理和防火墻中實(shí)現(xiàn)的連接跟蹤過(guò)程引起的,它們跟蹤通過(guò)它們的所有連接。

它們跟蹤通過(guò)它們的所有連接。由于這些機(jī)器的物理限制,它們只能在內(nèi)存中保留有限數(shù)量的連接。最常見(jiàn)和合乎邏輯的策略是保持最新的連接并首先丟棄舊的和不活動(dòng)的連接。

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

Linux下使用TCP keepalive

Linux 內(nèi)置了對(duì) keepalive 的支持。涉及 keepalive 的過(guò)程使用三個(gè)用戶驅(qū)動(dòng)的變量,可以使用 cat 查看參數(shù)值。

圖片

前兩個(gè)參數(shù)以秒表示,最后一個(gè)是純數(shù)字。這意味著keepalive 例程在發(fā)送第一個(gè)keepalive 探測(cè)之前等待兩個(gè)小時(shí)(7200 秒),然后每75 秒重新發(fā)送一次。如果連續(xù)9次沒(méi)有收到 ACK 響應(yīng),則連接被標(biāo)記為斷開(kāi)。

修改這個(gè)值很簡(jiǎn)單,可以這樣修改:

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

還有另一種訪問(wèn)內(nèi)核變量的方法,使用 sysctl 命令

圖片

setsockopt 、getsockopt 函數(shù)調(diào)用

在 Linux 操作系統(tǒng)中,我們可以通過(guò)代碼啟用一個(gè) socket 的心跳檢測(cè),為特定套接字啟用 keepalive 所需要做的就是在套接字本身上設(shè)置特定的套接字選項(xiàng)。函數(shù)原型如下:

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);

圖片

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

在編寫(xiě)應(yīng)用程序時(shí),還可以為 keepalive 設(shè)置其他三個(gè)套接字選項(xiàng)。它們都使用 SOL_TCP 級(jí)別而不是 SOL_SOCKET,并且它們僅針對(duì)當(dāng)前套接字覆蓋系統(tǒng)范圍的變量。如果不先寫(xiě)入就讀取,將返回當(dāng)前系統(tǒng)范圍的參數(shù)。

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

TCP keepalive 代碼實(shí)現(xiàn)

在寫(xiě)TCP keepalive 服務(wù)程序時(shí),除了要處理SIGPIPE外,還要有客戶端連接檢測(cè)機(jī)制,用于及時(shí)發(fā)現(xiàn)崩潰的客戶端連接。我們使用TCP的 keepalive 機(jī)制方式。

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[] )
{

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

   /* 檢查 keepalive 選項(xiàng)的狀態(tài)  */
   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"));

   /* 將選項(xiàng)設(shè)置為活動(dòng)  */
   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");

   /* 再次檢查狀態(tài)  */
   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 );
      /* 再次檢查狀態(tài)  */
   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);
      /* 再次檢查狀態(tài)  */
   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 );
  /* 初始化套接字結(jié)構(gòu) */
   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);

  ...
 }

圖片

圖片

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

通過(guò)測(cè)試程序,我們可以使用tcpdump、或者tshark是命令行抓包工具,來(lái)分析KeepAlive。

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

圖片

tcpdump -nn -i lo port 5050

圖片

整個(gè)keepalive過(guò)程很簡(jiǎn)單,就是client給server發(fā)送一個(gè)包,server返回給用戶一個(gè)包。注意包內(nèi)沒(méi)有數(shù)據(jù),只有ACK標(biāo)識(shí) 被打開(kāi)。

ps -aux | grep tcp_keepalive

圖片

總結(jié)

keepalive 是一個(gè)設(shè)備向另一個(gè)設(shè)備發(fā)送的消息,用于檢查兩者之間的鏈路是否正在運(yùn)行,或防止鏈路中斷。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 電源
    +關(guān)注

    關(guān)注

    185

    文章

    18995

    瀏覽量

    264672
  • TCP
    TCP
    +關(guān)注

    關(guān)注

    8

    文章

    1434

    瀏覽量

    83786
  • 程序
    +關(guān)注

    關(guān)注

    117

    文章

    3849

    瀏覽量

    85501
  • 網(wǎng)絡(luò)通信
    +關(guān)注

    關(guān)注

    4

    文章

    847

    瀏覽量

    32667
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    ESP32-S3使用tcp_server例程,將網(wǎng)絡(luò)數(shù)據(jù)和串口數(shù)據(jù)透?jìng)餮舆t過(guò)高怎么解決?

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

    ESP8266 TCP保持活動(dòng)狀態(tài)功能似乎不起作用,為什么?

    。 當(dāng)我為TCP客戶端設(shè)置保持活動(dòng)狀態(tài)參數(shù)時(shí): ... client_fd= socket(); ... int keepAlive = 1; //enable keepalive int
    發(fā)表于 07-12 08:00

    如何使用espconn_set_keepalive?

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

    使用esp_iot_sdk_v1.0.1_15_04_24時(shí)keepalive無(wú)效的原因?

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

    請(qǐng)問(wèn)ESP8266 SDK可以添加KeepAlive獲取狀態(tài)接口嗎?

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

    求助,關(guān)于AT+CIPSTART指令keepalive功能的問(wèn)題求解

    都沒(méi)有任何響應(yīng),所以也不知道具體是多久斷開(kāi)。 所以嘗試用AT+CIPSTART指令設(shè)置Keepalive功能來(lái)保持服務(wù)器連接,結(jié)果發(fā)現(xiàn)我設(shè)置成60秒,到了60秒就返回一個(gè)CLOSE。 一開(kāi)始我以為是
    發(fā)表于 07-16 07:47

    WICED中使能TCP保活后無(wú)法disconnected怎么解決?

    函數(shù),并開(kāi)啟Keepalive,在TCP非正常斷開(kāi)后(直接關(guān)閉WIFI而不是直接關(guān)閉TCP的連接,正常斷開(kāi)是能夠進(jìn)入斷開(kāi)的回調(diào)函數(shù)的),調(diào)試發(fā)現(xiàn)是能夠進(jìn)入
    發(fā)表于 07-08 06:57

    KeepAlive:組件緩存實(shí)現(xiàn)深度解析

    我們學(xué)習(xí)了 Suspense 如何處理異步組件加載。今天,我們將探索Vue3中另一個(gè)強(qiáng)大的特性:KeepAlive。它允許我們?cè)诮M件切換時(shí)緩存組件實(shí)例,避免重復(fù)渲染,極大地提升了用戶體驗(yàn)和性能
    發(fā)表于 03-05 19:17

    LWIP的keepalive功能TCP長(zhǎng)時(shí)間不再發(fā)送數(shù)據(jù)就會(huì)斷開(kāi)連接

    把LWIP中的keepalive功能打開(kāi)之后,如果協(xié)議棧檢測(cè)到TCP長(zhǎng)時(shí)間不再發(fā)送數(shù)據(jù)就會(huì)把連接斷開(kāi)。如果我在網(wǎng)絡(luò)正常通信的情況下突然拔掉網(wǎng)線,等到協(xié)議棧把TCP連接斷開(kāi)后,再插上網(wǎng)線,但是卻不能重新連接之前的
    發(fā)表于 04-06 04:36

    TCP實(shí)現(xiàn):TCP概要

    學(xué)習(xí)TCP-IP的很好的書(shū)。TCP-IP詳解卷3。
    發(fā)表于 05-09 16:07 ?0次下載

    TCP實(shí)現(xiàn):TCP函數(shù)

    學(xué)習(xí)TCP-IP的很好的書(shū)。TCP-IP詳解卷3。
    發(fā)表于 05-09 16:07 ?0次下載

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

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

    TCP keepalive機(jī)制具體是怎么樣的

    今天,聊一個(gè)有趣的問(wèn)題:拔掉網(wǎng)線幾秒,再插回去,原本的 TCP 連接還存在嗎?
    的頭像 發(fā)表于 03-11 16:50 ?3494次閱讀

    Keepalive基礎(chǔ)知識(shí)

    Keepalive 1 keepalived介紹 ? 官網(wǎng):http://keepalived.org/ ? 功能: 基于vrrp協(xié)議完成地址流動(dòng) 為vip地址所在的節(jié)點(diǎn)生成ipvs規(guī)則(在配置文件
    的頭像 發(fā)表于 12-19 09:57 ?1917次閱讀
    <b class='flag-5'>Keepalive</b>基礎(chǔ)知識(shí)

    第三章 W55MH32 TCP Client示例

    本文介紹在 W55MH32?芯片上實(shí)現(xiàn) TCP?客戶端模式進(jìn)行數(shù)據(jù)回環(huán)測(cè)試的方法。闡述 TCP?協(xié)議概念、特點(diǎn)、與 UDP?區(qū)別、應(yīng)用場(chǎng)景及相關(guān)機(jī)制。展示實(shí)現(xiàn)過(guò)程,包括開(kāi)啟 Keepalive?功能,在主循環(huán)運(yùn)行測(cè)試程序。燒錄例
    的頭像 發(fā)表于 07-24 09:06 ?1426次閱讀
    第三章 W55MH32 <b class='flag-5'>TCP</b> Client示例
    蓬莱市| 山丹县| 洛宁县| 巴林左旗| 锡林郭勒盟| 宜黄县| 廉江市| 襄垣县| 北辰区| 宜川县| 通辽市| 奇台县| 抚顺县| 蕉岭县| 罗源县| 长治县| 宁安市| 乌鲁木齐县| 剑川县| 长葛市| 米脂县| 葵青区| 左权县| 织金县| 太保市| 金寨县| 甘德县| 望江县| 浪卡子县| 客服| 龙州县| 松原市| 夏邑县| 陈巴尔虎旗| 铜鼓县| 饶阳县| 宜宾市| 和龙市| 岫岩| 桦川县| 商南县|