常用的 TCP KeepAlive 參數


轉自:http://dola.xinfan.org/?p=359

我們知道 TCP 協議有檢測連接狀態的機制,當連接不活躍的時候,連接雙方會通過一定的算法檢測連接是否正常。這個機制就是 TCP 的 KeepAlive 算法。

如果不使用 KeepAlive 算法檢測連接狀態,會導致單方面斷開連接后,另一方無法感知。比如 A 在用 recv 函數等待 B 發送數據,但這時候 B 已經失效,A 會一直等在 recv 函數上不能返回。

要啟用 KeepAlive,我們要使用 setsockopt 函數來實現。在 Python 中是這么做的:

1
2
3
4
5
6
#!/usr/bin/env python
 
import socket
 
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1 )

最后一個參數1表示啟用 KeepAlive。程序會使用系統默認的參數進行連接狀態檢測。

在 Debian 操作系統中,默認在連接 idle 7200 秒(/proc/sys/net/ipv4/tcp_keepalive_time)后才發送第一個 KeepAlive 狀態檢測包,整整兩個小時,着實有點長,對有些應用場景不太適合。因此,我們通常需要調整觸發 KeepAlive 的 idle 時間間隔:

1
s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 10 )

最后一個參數 10 表示在連接不活躍 10s 后開始 KeepAlive 檢測。

開始 KeepAlive 檢測之后,程序會每隔一定時間發送一次 KeepAlive 狀態檢測包,Debian 操作系統下默認是 75 秒(/proc/sys/net/ipv4/tcp_keepalive_intvl)發送一次,我們也可以在程序中定義這個發送間隔:

1
s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 6 )

最后一個參數表示每隔 6s 發送一次。

連接的另一方收到 KeepAlive 狀態檢測包后會發送一個響應包,表示還活着。如果對方未及時發送響應包,程序會對失敗次數進行記錄,Debian 操作系統中如果連續 9 次(/proc/sys/net/ipv4/tcp_keepalive_probe)失敗,會認為對方已經失效,會觸發連接異常操作,中斷所有正在進行的操作,比如 recv 會返回 -1,並設置 error code 為 Broken Pipe。當然,我們也可以在程序中定義允許失敗的次數:

1
s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 3 )

在這個例子中,我們把它設置成了 3 次。

在 Linux 操作系統中,我們可以使用 netstat 工具使用 –timer 參數來查看當前系統中的 tcp 連接的 KeepAlive 狀態:

1
2
3
4
5
6
7
8
# netstat -anplt --timer
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID /Program name Timer
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      2066 /sshd        off (0.00 /0/0 )
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      2012 /mysqld      off (0.00 /0/0 )
tcp        0      0 172.16.10.23:22         172.16.10.1:46726       ESTABLISHED 7280 /0           keepalive (5053.74 /0/0 )
tcp6       0      0 :::80                   :::*                    LISTEN      7150 /apache2     off (0.00 /0/0 )
tcp6       0      0 :::22                   :::*                    LISTEN      2066 /sshd        off (0.00 /0/0 )


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM