socket keepalive理解
參考URL: https://www.cnblogs.com/xiao-tao/p/9718017.html
java socket編程中有個keepalive選項,看到這個選項經常會誤解爲長連接,不設置則爲短連接,實則不然。
socket連接建立之後,只要雙方均未主動關閉連接,那這個連接就是會一直保持的,就是持久的連接。keepalive只是爲了防止連接的雙方發生意外而通知不到對方,導致一方還持有連接,佔用資源。
其實這個選項的意思是TCP連接空閒時是否需要向對方發送探測包,實際上是依賴於底層的TCP模塊實現的,java中只能設置是否開啓,不能設置其詳細參數,只能依賴於系統配置。
SocketOptions.java 部分源碼
/**
* When the keepalive option is set for a TCP socket and no data
* has been exchanged across the socket in either direction for
* 2 hours (NOTE: the actual value is implementation dependent),
* TCP automatically sends a keepalive probe to the peer. This probe is a
* TCP segment to which the peer must respond.
* One of three responses is expected:
* 1. The peer responds with the expected ACK. The application is not
* notified (since everything is OK). TCP will send another probe
* following another 2 hours of inactivity.
* 2. The peer responds with an RST, which tells the local TCP that
* the peer host has crashed and rebooted. The socket is closed.
* 3. There is no response from the peer. The socket is closed.
*
* The purpose of this option is to detect if the peer host crashes.
*
* Valid only for TCP socket: SocketImpl
*
* @see Socket#setKeepAlive
* @see Socket#getKeepAlive
*/
@Native public final static int SO_KEEPALIVE = 0x0008;
源碼的意思是,如果這個連接上雙方任意方向在2小時之內沒有發送過數據,那麼tcp會自動發送一個探測探測包給對方,這種探測包對方是必須迴應的,迴應結果有三種:
1.正常ack,繼續保持連接;
2.對方響應rst信號,雙方重新連接。
3.對方無響應。
這裏說的兩小時,其實是依賴於系統配置
在linux系統中(windows在註冊表中,可以自行查詢資料),tcp的keepalive參數
linux下查看相關命令
[root@VM_0_14_centos ~]# echo /proc/sys/net/ipv4/tcp_keepalive* | xargs -n 1 strings -1 -f
/proc/sys/net/ipv4/tcp_keepalive_intvl: 75
/proc/sys/net/ipv4/tcp_keepalive_probes: 9
/proc/sys/net/ipv4/tcp_keepalive_time: 7200
[root@VM_0_14_centos ~]#
/proc/sys/net/ipv4/tcp_keepalive_time 當keepalive起用的時候,TCP發送keepalive消息的頻度。默認是2小時。
/proc/sys/net/ipv4/tcp_keepalive_intvl 當探測沒有確認時,keepalive探測包的發送間隔。缺省是75秒。
/proc/sys/net/ipv4/tcp_keepalive_probes 如果對方不予應答,keepalive探測包的發送次數。缺省值是9。
總結:net.ipv4.tcp_keepalive_intvl = 75 (發送探測包的週期,前提是當前連接一直沒有數據交互,纔會以該頻率進行發送探測包,如果中途有數據交互,則會重新計時tcp_keepalive_time,到達規定時間沒有數據交互,纔會重新以該頻率發送探測包)
net.ipv4.tcp_keepalive_probes = 9 (探測失敗的重試次數,發送探測包達次數限制對方依舊沒有迴應,則關閉自己這端的連接)
net.ipv4.tcp_keepalive_time = 7200 (空閒多長時間,則發送探測包)