默認http1.1協議的請求頭是默認開啟keepalive,如圖:
那什么是keepalive?作用是什么?
keepalive是在TCP中一個可以檢測死連接的機制,作用是保持socket長連接不被斷開,屬于tcp層的功能,并不屬于應用層。
TCP層怎么做到保持長連接的呢?
先看keepalive的用法:有三個參數,開放給應用層使用
sk->keepalive_probes:探測次數,重試次數sk->keepalive_time 探測的心跳間隔,TCP鏈接在多少秒之后沒有數據報文傳輸啟動探測報文sk->keepalive_intvl 探測間隔,未收到回復時,重試的時間間隔
默認配置查看:
[***@*** ~]$ cat /proc/sys/net/ipv4/tcp_keepalive_time7200[***@*** ~]$ cat /proc/sys/net/ipv4/tcp_keepalive_intvl75[***@*** ~]$ cat /proc/sys/net/ipv4/tcp_keepalive_probes9
使用方法:
int keepalive = 1; // 開啟keepalive屬性int keepidle = 60; // 如該連接在60秒內沒有任何數據往來,則進行探測int keepinterval = 5; // 探測時發包的時間間隔為5 秒int keepcount = 3; // 探測嘗試的次數。如果第1次探測包就收到響應了,則后2次的不再發。并且清零該計數setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive , sizeof(keepalive ));setsockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void*)&keepidle , sizeof(keepidle ));setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void *)&keepinterval , sizeof(keepinterval ));setsockopt(rs, SOL_TCP, TCP_KEEPCNT, (void *)&keepcount , sizeof(keepcount ));
應用層這么設置后,會把默認配置覆蓋,走手動設置的配置。
對于一個已經建立的tcp連接。如果在keepalive_time時間內雙方沒有任何的數據包傳輸,則開啟keepalive功能的一端將發送 keepalive數據心跳包,若沒有收到應答,則每隔keepalive_intvl時間再發送該數據包,發送keepalive_probes次。一直沒有 收到應答,則發送rst包關閉連接。若收到應答,則將計時器清零。
抓包驗證tcp心跳包內容
根據抓包繼續分析keepalive發送及回復的心跳包內容:
tcp頭部結構體源碼為:
typedef struct _TCP_HEADER{ short m_sSourPort; // 源端口號16bit short m_sDestPort; // 目的端口號16bit unsigned int m_uiSequNum; // req字段 序列號32bit unsigned int m_uiAcknowledgeNum; //ack字段 確認號32bit short m_sHeaderLenAndFlag; // 前4位:TCP頭長度;中6位:保留;后6位:標志位 short m_sWindowSize; //win字段 窗口大小16bit short m_sCheckSum; // 檢驗和16bit short m_surgentPointer; // 緊急數據偏移量16bit}__attribute__((packed))TCP_HEADER, *PTCP_HEADER;
新聞熱點
疑難解答