1. 程式人生 > >關於面試經常被問到的socket的TIME_WAIT狀態的原因及解決辦法和避免的辦法

關於面試經常被問到的socket的TIME_WAIT狀態的原因及解決辦法和避免的辦法

一檢視現在time_wait的數量及淺析

    netstat -an | grep TIME_WAIT | wc -l 

發現系統存在大量TIME_WAIT狀態的連線,通過調整核心引數解決,在 /etc/sysctl.conf中加入

net.ipv4.tcp_tw_recycle = 1    (表示開啟TCP連線中TIME-WAIT sockets的快速回收,預設為0,表示關閉)

建立TCP需要3次握手,而終止TCP需要4次互動;


主動關閉socket的一方最終為time_wait,被動關閉的則為close_wait;


為什麼time_wait需要2*MSL等待時間?
MSL就是maximum segment lifetime(最大分節生命期),這是一個IP資料包能在網際網路上生存的最長時間,超過這個時間將在網路中消失。


假設最終的 ACK 丟失 , server 將重發 FIN , client 必須維護 TCP 狀態資訊以便可以重發最終的 ACK ,否則會發送RST ,結果 server 認為發生錯誤。 
若要TCP可靠地終止連線的兩個方向 ( 全雙工關閉 ) , client 必須進 TIME_WAIT狀態。
現在我們考慮終止連線時的被動方傳送了一個FIN,然後主動方回覆了一個ACK,然而這個ACK可能會丟失,這會造成被動方重發FIN,這個FIN可能會在網際網路上存活MSL。
如果沒有TIME_WAIT的話,假設連線1已經斷開,然而其被動方最後重發的那個FIN(或者FIN之前傳送的任何TCP分段)還在網路上,然而連線2重用了連線1的所有的5元素(源IP,目的IP,TCP,源埠,目的埠),剛剛將建立好連線,連線1遲到的FIN到達了,這個FIN將以比較低但是確實可能的概率終止掉連線2.



如何消除大量TCP短連線引發的TIME_WAIT?
1)可以改為長連線,但代價較大,長連線太多會導致伺服器效能問題,而且PHP等指令碼語言,需要通過proxy之類的軟體才能實現長連線;
2)修改ipv4.ip_local_port_range,增大可用埠範圍,但只能緩解問題,不能根本解決問題;
3)客戶端程式中設定socket的SO_LINGER選項;
4)客戶端機器開啟tcp_tw_recycle和tcp_timestamps選項;
5)客戶端機器開啟tcp_tw_reuse和tcp_timestamps選項;
6)客戶端機器設定tcp_max_tw_buckets為一個很小的值

So_linger的作用

struct linger {
     int l_onoff; /* 0 = off, nozero = on */
     int l_linger; /* linger time */
};
其取值和處理如下:
1、設定 l_onoff為0,則該選項關閉,l_linger的值被忽略,等於核心預設情況,close呼叫會立即返回給呼叫者,如果可能將會傳輸任何未傳送的資料;
2、設定 l_onoff !=0 && l_linger = 0,則套介面關閉時TCP夭折連線,TCP將丟棄保留在套介面傳送緩衝區中的任何資料併發送一個RST給對方,而不是通常的四分組終止序列,這避免了TIME_WAIT狀態;
3、設定 l_onoff != 0 && l_linger != 0,當套介面關閉時核心將拖延一段時間(由l_linger決定)。

1、 若設定了SO_LINGER(亦即linger結構中的l_onoff域設為非零),並設定了零超時間隔,則closesocket()不被阻塞立即執行,不論是否有排隊資料未傳送或未被確認。這種關閉方式稱為 “強制”或“失效”關閉 ,因為套介面的虛電路立即被複位,且丟失了未傳送的資料。在遠端的recv()呼叫將以WSAECONNRESET出錯。 
2、 若設定了SO_LINGER並確定了非零的超時間隔,則closesocket()呼叫阻塞程序,直到所剩資料傳送完畢或超時。這種關閉稱為 “優雅”或“從容”關閉 。請注意如果套介面置為非阻塞且SO_LINGER設為非零超時,則closesocket()呼叫將以WSAEWOULDBLOCK錯誤返回。 
3、 若在一個流類套介面上設定了SO_DONTLINGER(也就是說將linger結構的l_onoff域設為零),則closesocket()呼叫立即返回。但是,如果可能,排隊的資料將在套介面關閉前傳送。請注意,在這種情況下WINDOWS套介面實現將在一段不確定的時間內保留套介面以及其他資源,這對於想用所以套介面的應用程式來說有一定影響。 

如果套介面緩衝區中仍殘留資料,程序將處於睡眠狀態,直到
(a)所有資料傳送完且被對方確認,之後進行正常的終止序列(描述字訪問計數為0)
 或(b)延遲時間到。
此種情況下,應用程式檢查close的返回值是非常重要的,如果在資料傳送完並被確認前時間到,close將返回EWOULDBLOCK錯誤且套介面傳送緩衝區中的任何資料都丟失。

close的成功返回僅告訴我們傳送的資料(和FIN)已由對方TCP確認,它並不能告訴我們對方應用程序是否已讀了資料。如果套介面設為非阻塞的,它將不等待close完成。


tcp_tw_recycle
tcp_tw_recycle選項作用為:Enable fast recycling TIME-WAIT sockets. Default value is 0.
tcp_timestamps選項作用為:TCP timestamps are used to provide protection against wrapped sequence numbers. 預設值為1。
1)快速回收到底有多快?
2)有的資料說只要開啟tcp_tw_recycle即可,有的又說要tcp_timestamps同時開啟,具體是哪個正確?
3)為什麼從虛擬機器NAT出去發起客戶端連線時選項無效,非虛擬機器連線就有效?
計算快速回收的時間,等於 RTO * 3.5,回答第一個問題的關鍵是RTO(Retransmission Timeout)大概是多少
RFC中有關於RTO計算的詳細規定,一共有三個:RFC-793、RFC-2988、RFC-6298,Linux的實現是參考RFC-2988。
=====linux-2.6.37 net/ipv4/tcp.c 126================
#define TCP_RTO_MAX ((unsigned)(120*HZ))
#define TCP_RTO_MIN ((unsigned)(HZ/5))
==========================================
這裡的HZ是1s,因此可以得出RTO最大是120s,最小是200ms,對於區域網的機器來說,正常情況下RTO基本上就是200ms,因此3.5 RTO就是700ms
1)快速回收到底有多快?
區域網環境下,700ms就回收;
2)有的資料說只要開啟tcp_tw_recycle即可,有的又說要tcp_timestamps同時開啟,具體是哪個正確?
需要同時開啟,但預設情況下tcp_timestamps就是開啟的,所以會有人說只要開啟tcp_tw_recycle即可;
3)為什麼從虛擬機發起客戶端連線時選項無效,非虛擬機器連線就有效?
和網路組網有關係,無法獲取對端資訊時就不進行快速回收;


tcp_tw_reuse
tcp_tw_reuse選項的含義如下
tcp_tw_reuse - BOOLEAN
Allow to reuse TIME-WAIT sockets for new connections when it is safe from protocol viewpoint. Default value is 0.
這裡的關鍵在於“協議什麼情況下認為是安全的”,由於環境限制,沒有辦法進行驗證,通過看原始碼簡單分析了一下。
=====linux-2.6.37 net/ipv4/tcp_ipv4.c 114=====
int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
總結一下:
1)tcp_tw_reuse選項和tcp_timestamps選項也必須同時開啟;
2)重用TIME_WAIT的條件是收到最後一個包後超過1s。
官方手冊有一段警告:
It should not be changed without advice/request of technical experts.
對於大部分區域網或者公司內網應用來說,滿足條件2)都是沒有問題的,因此官方手冊裡面的警告其實也沒那麼可怕:)


tcp_max_tw_buckets
參考官方文件(http://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt),解釋如下:
tcp_max_tw_buckets - INTEGER
Maximal number of timewait sockets held by system simultaneously. If this number is exceeded time-wait socket is immediately destroyed and warning is printed. 
官方文件沒有說明預設值,通過幾個系統的簡單驗證,初步確定預設值是180000。
官方手冊中有一段警告:
    This limit exists only to prevent simple DoS attacks, you _must_ not lower the limit artificially, but rather increase it (probably, after increasing installed memory),if network conditions require more than default value.
基本意思是這個用於防止Dos攻擊,我們不應該人工減少,如果網路條件需要的話,反而應該增加。

二.出現原因分析

TCP連線的終止 
TCP建立一個連線至少需要交換三個分組,也因此稱之為TCP的三路握手(three-way handshake),然而在TCP終止連線時,由於雙方都需要傳送一個FIN分節給對端確認,因此TCP終止連線一般是需要交換四個分節。具體來看: 

1、 應用程序(active close)首先呼叫close,於是導致TCP傳送一個FIN分節,表示資料已分送完畢,請求關閉套接字。 
2、 另一端應用程序(passive close)接受收到FIN,並由該端的TCP確認(確認的過程是TCP傳送ACK分節給對端套接字)。FIN的接受也作為檔案結束符傳遞給上層應用程序。這裡的檔案結束符並非應用程序的EOF,在TCP位元組流中,EOF的讀或寫通過收發一個特殊的FIN分節來實現。 
3、 另端(passive close)應用程序在接受到檔案束符後,會呼叫close關閉它的套接字,這導致該端的TCP也傳送了一個FIN分節。 
4、 主動關閉端(active close)接受到這個FIN後,TCP對它進行確認。(TCP傳送ACK分節,值得注意的是主動關閉端在未接受到FIN之前,它的狀態就是TIME_WAIT)。




綜上所述:TIME_WAIT狀態出現場景是主動關閉端在未接受到FIN之前,它的狀態就是TIME_WAIT。

二.TCP為什麼如此設計

1。防止上一次連線中的包(特別是最後一個ACK包),迷路後重新出現,影響新連線  (經過2MSL(max segment lifetime),上一次連線中所有的重複包都會消失)。
2。可靠的關閉TCP連線  在主動關閉方傳送的最後一個 ack(fin) ,有可能丟失,這時被動方會重新發
  fin, 如果這時主動方處於 CLOSED 狀態 ,就會響應 rst 而不是 ack。所以  主動方要處於 TIME_WAIT 狀態,而不能是 CLOSED 。TIME_WAIT 並不會佔用很大資源的,除非受到攻擊。還有,如果一方 send 或 recv 超時,就會直接進入 CLOSED 狀態。

三.規避大量出現TIME_WAIT的方法

net.ipv4.tcp_tw_reuse和net.ipv4.tcp_tw_recycle的開啟都是為了回收處於TIME_WAIT狀態的資源。
net.ipv4.tcp_fin_timeout這個時間可以減少在異常情況下伺服器從FIN-WAIT-2轉到TIME_WAIT的時間。
net.ipv4.tcp_keepalive_*一系列引數,是用來設定伺服器檢測連線存活的相關配置。

在伺服器的日常維護過程中,會經常用到下面的命令:

  1. netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'    

它會顯示例如下面的資訊:

TIME_WAIT 814
CLOSE_WAIT 1
FIN_WAIT1 1
ESTABLISHED 634
SYN_RECV 2
LAST_ACK 1

常用的三個狀態是:ESTABLISHED 表示正在通訊,TIME_WAIT 表示主動關閉,CLOSE_WAIT 表示被動關閉。

ps:以上為自己總結網上各個blog的內容,方便自己掌握知識點用!

四.三次握手的詳細描述

  1. 第一次握手:建立連線。客戶端傳送連線請求報文段,將SYN位置為1,Sequence Number為x;然後,客戶端進入SYN_SEND狀態,等待伺服器的確認;
  2. 第二次握手:伺服器收到SYN報文段。伺服器收到客戶端的SYN報文段,需要對這個SYN報文段進行確認,設定Acknowledgment Number為x+1(Sequence Number+1);同時,自己自己還要傳送SYN請求資訊,將SYN位置為1,Sequence Number為y;伺服器端將上述所有資訊放到一個報文段(即SYN+ACK報文段)中,一併傳送給客戶端,此時伺服器進入SYN_RECV狀態;
  3. 第三次握手:客戶端收到伺服器的SYN+ACK報文段。然後將Acknowledgment Number設定為y+1,向伺服器傳送ACK報文段,這個報文段傳送完畢以後,客戶端和伺服器端都進入ESTABLISHED狀態,完成TCP三次握手。

完成了三次握手,客戶端和伺服器端就可以開始傳送資料。以上就是TCP三次握手的總體介紹。

為什麼要三次握手

既然總結了TCP的三次握手,那為什麼非要三次呢?怎麼覺得兩次就可以完成了。那TCP為什麼非要進行三次連線呢?在謝希仁的《計算機網路》中是這樣說的:

為了防止已失效的連線請求報文段突然又傳送到了服務端,因而產生錯誤。

在書中同時舉了一個例子,如下:

“已失效的連線請求報文段”的產生在這樣一種情況下:client發出的第一個連線請求報文段並沒有丟失,而是在某個網路結點長時間的滯留了,以致延誤到連線釋放以後的某個時間才到達server。本來這是一個早已失效的報文段。但server收到此失效的連線請求報文段後,就誤認為是client再次發出的一個新的連線請求。於是就向client發出確認報文段,同意建立連線。假設不採用“三次握手”,那麼只要server發出確認,新的連線就建立了。由於現在client並沒有發出建立連線的請求,因此不會理睬server的確認,也不會向server傳送資料。但server卻以為新的運輸連線已經建立,並一直等待client發來資料。這樣,server的很多資源就白白浪費掉了。採用“三次握手”的辦法可以防止上述現象發生。例如剛才那種情況,client不會向server的確認發出確認。server由於收不到確認,就知道client並沒有要求建立連線。”

這就很明白了,防止了伺服器端的一直等待而浪費資源。


五。四次揮手的詳細描述

當客戶端和伺服器通過三次握手建立了TCP連線以後,當資料傳送完畢,肯定是要斷開TCP連線的啊。那對於TCP的斷開連線,這裡就有了神祕的“四次分手”。

  1. 第一次分手:主機1(可以使客戶端,也可以是伺服器端),設定Sequence NumberAcknowledgment Number,向主機2傳送一個FIN報文段;此時,主機1進入FIN_WAIT_1狀態;這表示主機1沒有資料要傳送給主機2了;
  2. 第二次分手:主機2收到了主機1傳送的FIN報文段,向主機1回一個ACK報文段,Acknowledgment NumberSequence Number加1;主機1進入FIN_WAIT_2狀態;主機2告訴主機1,我也沒有資料要傳送了,可以進行關閉連線了;
  3. 第三次分手:主機2向主機1傳送FIN報文段,請求關閉連線,同時主機2進入CLOSE_WAIT狀態;
  4. 第四次分手:主機1收到主機2傳送的FIN報文段,向主機2傳送ACK報文段,然後主機1進入TIME_WAIT狀態;主機2收到主機1的ACK報文段以後,就關閉連線;此時,主機1等待2MSL後依然沒有收到回覆,則證明Server端已正常關閉,那好,主機1也可以關閉連線了。

至此,TCP的四次分手就這麼愉快的完成了。當你看到這裡,你的腦子裡會有很多的疑問,很多的不懂,感覺很凌亂;沒事,我們繼續總結。

為什麼要四次分手

那四次分手又是為何呢?TCP協議是一種面向連線的、可靠的、基於位元組流的運輸層通訊協議。TCP是全雙工模式,這就意味著,當主機1發出FIN報文段時,只是表示主機1已經沒有資料要傳送了,主機1告訴主機2,它的資料已經全部發送完畢了;但是,這個時候主機1還是可以接受來自主機2的資料;當主機2返回ACK報文段時,表示它已經知道主機1沒有資料傳送了,但是主機2還是可以傳送資料到主機1的;當主機2也傳送了FIN報文段時,這個時候就表示主機2也沒有資料要傳送了,就會告訴主機1,我也沒有資料要傳送了,之後彼此就會愉快的中斷這次TCP連線。如果要正確的理解四次分手的原理,就需要了解四次分手過程中的狀態變化。

  • FIN_WAIT_1: 這個狀態要好好解釋一下,其實FIN_WAIT_1FIN_WAIT_2狀態的真正含義都是表示等待對方的FIN報文。而這兩種狀態的區別是:FIN_WAIT_1狀態實際上是當SOCKET在ESTABLISHED狀態時,它想主動關閉連線,向對方傳送了FIN報文,此時該SOCKET即進入到FIN_WAIT_1狀態。而當對方迴應ACK報文後,則進入到FIN_WAIT_2狀態,當然在實際的正常情況下,無論對方何種情況下,都應該馬上回應ACK報文,所以FIN_WAIT_1狀態一般是比較難見到的,而FIN_WAIT_2狀態還有時常常可以用netstat看到。(主動方)
  • FIN_WAIT_2:上面已經詳細解釋了這種狀態,實際上FIN_WAIT_2狀態下的SOCKET,表示半連線,也即有一方要求close連線,但另外還告訴對方,我暫時還有點資料需要傳送給你(ACK資訊),稍後再關閉連線。(主動方)
  • CLOSE_WAIT:這種狀態的含義其實是表示在等待關閉。怎麼理解呢?當對方close一個SOCKET後傳送FIN報文給自己,你係統毫無疑問地會迴應一個ACK報文給對方,此時則進入到CLOSE_WAIT狀態。接下來呢,實際上你真正需要考慮的事情是察看你是否還有資料傳送給對方,如果沒有的話,那麼你也就可以 close這個SOCKET,傳送FIN報文給對方,也即關閉連線。所以你在CLOSE_WAIT狀態下,需要完成的事情是等待你去關閉連線。(被動方)
  • LAST_ACK: 這個狀態還是比較容易好理解的,它是被動關閉一方在傳送FIN報文後,最後等待對方的ACK報文。當收到ACK報文後,也即可以進入到CLOSED可用狀態了。(被動方)
  • TIME_WAIT: 表示收到了對方的FIN報文,併發送出了ACK報文,就等2MSL後即可回到CLOSED可用狀態了。如果FINWAIT1狀態下,收到了對方同時帶FIN標誌和ACK標誌的報文時,可以直接進入到TIME_WAIT狀態,而無須經過FIN_WAIT_2狀態。(主動方)
  • CLOSED: 表示連線中斷。


相關推薦

關於面試經常到的socket的TIME_WAIT狀態原因解決辦法避免辦法

一檢視現在time_wait的數量及淺析     netstat -an | grep TIME_WAIT | wc -l  發現系統存在大量TIME_WAIT狀態的連線,通過調整核心引數解決,在 /etc/sysctl.conf中加入net.ipv4.tcp_tw_r

getpost的區別--面試經常到!(一)

修改 史記 限制 url地址 完整 返回 協議頭 作用 delet 了解歷史 get和post是HTTP與服務器交互的方式, 說到方式,其實總共有四種:put,delete,post,get。 他們的作用分別是對服務器資源的增,刪,改,查。 所以,get是獲取數據,po

[偶爾遇到]找不到mysql.sock的出現原因解決方案mysql 預設mysql.sock位置預設問題探討 不指定

背景:(1)偶爾會出現mysql的server和mysql的client預設的socke檔案不在一個地方,我們用mysql時會出現一個找不到mysql.sock的情況。(2)因非正常關機出現:/tmp/mysql.sock 不見了,找不到了,如何連線上去的問題?(其他機器通過

網際網路公司面試經常的問題

機器學習 1.(騰訊)SVM的原理是什麼? 參考答案: 支援向量機(SVM)第一種二類分類模型,它的基本模型是定義在特徵空間上的間隔最大的線性分類器,間隔最大使它有別於感知機;支援向量機還包括核技巧,這使它成為實質上的非線性分類器。硬幾何最大化解決線性可分

面試時最經常到的問題(Frenquently asked interview questions)(II)

面試時最經常被問到的問題(Frenquently asked interview questions)之Analytical, puzzles, and brain-teasers篇 Analytical, puzzles, and brain-teasers Questio

面試經常到springboot版本問題

一、Spring Boot 版本支援Spring BootSpring FrameworkJavaMavenGradle1.2.0之前版本63.0+1.6+1.2.04.1.3+3.2+1.12+1.2

機器學習LR模型,在面試經常到的問題

     面試機器學習崗位或者演算法崗位,經常會被問到一些機器學習演算法,其中還有很多細節性的知識。在面試中接觸到的LR模型是最多的,為什麼?大概原因是LR在公司中用的比較多,這時你可能會問了,這個演

Java面試常會到的經典面試題,學習或者求職,你都要好好掌握

cookie 異常類 shu data 區別 origin 目的 tro jdk和jre Java現在的熱度雖然有所下降,但是,學Java的人依舊很多。。Java的崗位也是滲透很多。那麽,那些經典的Java知識點,你能看到問題就能說出一二三嗎?來一起看看。。 1.JDK和

經常到的面試題1

經常被問到的面試題1 行內元素有哪些?塊級元素有哪些? 空(void)元素有那些? CSS規範規定,每個元素都有display屬性,確定該元素的型別,每個元素都有預設的display值,如div的display預設值為“block”,則為“塊級”元素;span預設display屬性值為“inline”,是

3到5年工作經驗是如何回答面試到的Java集合框架問題

可能很多人會問Java集合真的那麼重要嗎,就像為什麼現在很多企業都喜歡先問演算法一樣,目的就是考察你對Java基礎掌握的程度如何。下面我將列出了一些關於Java集合的重要問題,讓我們一起看看3到5年的Java開發工程師是如何回答這些問題的。 Java集合中 List、Set、M

vue中經常到的面試題

一、對於MVVM的理解? MVVM 是 Model-View-ViewModel 的縮寫。 Model 代表資料模型,也可以在Model中定義資料修改和操作的業務邏輯。 View 代表UI 元件,它負責將資料模型轉化成UI 展現出來。 View

應用提交Appstore上架拒的原因解決方法

導讀:最近專案提交app store時,遇到了好幾次被拒的情況,總結了幾個遇到的問題及解決方法。 一、上傳打包時 報錯:提示缺少某個尺寸的圖示 解決方法: (1)AppIcon圖示尺寸:AppIcon (6張) AppStore Icon (1張)(png格式)

快速排序是常考找工作經常到的排序方式,需要重要掌握

package eighty; public class Kuaisupaixu {      public static void main(String[] args) {          //快速排序,將長度

面試到“為什麼從上一個單位離職”怎麼回答

        很多朋友都問這樣一個問題,在應聘一家公司面試時,面試官問:“你為什麼想到要離開現在這家XX公司?”都不知道該怎麼回答。      其實,面試官這個問題可以算是一句客套話,就和朋友之間問“最近忙什麼呢”“最

TIME_WAIT狀態原因解決辦法

socket相關索引:https://blog.csdn.net/knowledgebao/article/details/84626184 linux下通過netstat -ano命令,可以檢視到關於socket的狀態: 包括:FIN_WAIT_1、FIN_WAIT_2、CLOSE_

iOS上架原因解決辦法

簡單的記錄一下,近期APP上架所遇到的坑爹事兒吧!! 第一次提交: 第二天給了回覆,內容如下: 1、Guideline 2.5.1 - Performance - Software Requirements Your app uses the "prefs:root=" non-public U

網際網路公司面試經常的Redis題目

Redis是一個非常火的非關係型資料庫,火到什麼程度呢?只要是一個網際網路公司都會使用到。Redis相關的問題可以說是面試必問的,下面我從個人當面試官的經驗,總結幾個必須要掌握的知識點。(知識點較多,我整理了個思維導圖,後臺回覆redis,傳送給你) 介紹:Redis 是一個開源的使用 ANSI C 語言編寫

區塊鏈技術面試到的Hyberledger Fabric關鍵概念

###總覽Overview 介紹 Hyberledger Fabric 做為一個全面、可定製、企業級區塊鏈解決方案關鍵設計需求: Assets (資產) - 資產定義了可以交換的幾乎所有東西,其能通過網路用錢計價,從食物、到古董車、到未來的貨幣。 Chain

程式設計師面試阿里讀過最有力量的文字,網友:後悔建立阿里巴巴

網際網路可以說是現在一個很有趣的領域了,以程式設計師為主體,如今90後程序員思維都相對開放和多元,即使面試也不像從前那樣單挑和嚴肅,我們可以看到許多面試題都是很奇怪的,小編曾經就看到一個面試題是如果你在沙漠只有一元錢卻買不起水該怎麼辦,大家回答千奇百怪,而有一名程式設計師則回答出來了,就是走出去。很

Java面試到的題目+解答

內部類是一個類內部類的統稱,具體分為四種:成員類,靜態成員類,區域性類,匿名類。其中匿名類是區域性類的特殊情況。對於成員類和靜態成員類都存在於類的頂層程式碼中。相當於類的靜態方法和非靜態方法的關係。區別在於成員類依賴於類例項而靜態成員類不依賴。所以前者只能訪問例項方法和成員而後者只能訪問靜態方法和成員。它們都