前言
相信大家在面試的時(shí)候時(shí)不時(shí)會(huì)遇到考官會(huì)問(wèn)這種問(wèn)題瓦呼,在大學(xué)的時(shí)候我們應(yīng)該都學(xué)過(guò)這種基礎(chǔ)知識(shí)涨共,當(dāng)時(shí)應(yīng)該是背的滾瓜爛熟的岖寞,只不過(guò)到了社會(huì)上以后抡四,大家可能跟這個(gè)接觸少了,慢慢就淡忘了仗谆。這個(gè)并不是什么特別牛逼的問(wèn)題床嫌,知道也不是什么了不起的事情,就像java每個(gè)基礎(chǔ)類(lèi)型占多少字節(jié)胸私,bit和byte的轉(zhuǎn)化厌处,等等。你不知道吧岁疼,對(duì)于我們安卓開(kāi)發(fā)者來(lái)說(shuō)問(wèn)題不是很大阔涉,項(xiàng)目,工程也能搞起來(lái)捷绒,你知道了吧瑰排,好像也就那樣,會(huì)者不難也不是了不起的事情暖侨。很久之前我之前有家公司的面試官就問(wèn)了這個(gè)問(wèn)題椭住,我心里想mmp,面試造火箭呢這字逗?京郑!直到后來(lái)項(xiàng)目越做越大,整個(gè)安卓項(xiàng)目過(guò)于龐大葫掉,有些地方出現(xiàn)了卡頓些举,但是卻無(wú)從下手,有人說(shuō)俭厚,問(wèn)百度啊户魏。要是真遇到了某個(gè)問(wèn)題,真的是很難形容挪挤,有報(bào)錯(cuò)還好叼丑,但是你說(shuō)卡頓,優(yōu)化這種事情扛门,百度上一搜茫茫多鸠信,找出來(lái)的文章也是人寫(xiě)的,也可能會(huì)誤導(dǎo)你尖飞。這個(gè)時(shí)候症副,如果基本功好店雅,就很容易從現(xiàn)象看本質(zhì),針對(duì)性地解決問(wèn)題贞铣。
說(shuō)的有點(diǎn)多闹啦,下面割一下就進(jìn)入正題。
幾個(gè)英文單詞縮寫(xiě)的含義
SYN:synchronous 意思是建立聯(lián)機(jī)
SYN_SEND:發(fā)送了
SYN_RCVD:接收了
ESTABLISHED:建立了
ACK:確認(rèn)
seq:序列號(hào)
大致理解了這幾個(gè)英文單詞的縮寫(xiě)含義后辕坝,我們?cè)偃タ纯慈挝帐趾退拇螕]手會(huì)事半功倍窍奋。
TCP的三次握手
- 客戶(hù)端發(fā)起連接,將SYN置為1酱畅,同時(shí)給服務(wù)端發(fā)送一個(gè)序列號(hào)琳袄,seq = J,這時(shí)候客戶(hù)端的狀態(tài)是已經(jīng)發(fā)送SYN_SEND纺酸;
- 服務(wù)端接收到了信號(hào)后窖逗,重置了ACK = 1,SYN = 1餐蔬,同時(shí)會(huì)將客戶(hù)端的序列號(hào)加一然后賦值給ack碎紊,再帶入自己的序列號(hào),seq = K并返回給客戶(hù)端樊诺,這時(shí)候服務(wù)端會(huì)將自己的狀態(tài)置為已收到SYN_RCVD仗考;
- 客戶(hù)端在收到了服務(wù)端的報(bào)文后,會(huì)首先看下服務(wù)端是不是收到了自己發(fā)的東西词爬,就是判斷ack的值是不是已經(jīng)被+1了秃嗜,然后會(huì)把服務(wù)端發(fā)送的序列號(hào)+1并賦值給ack,同時(shí)將自己的狀態(tài)置為ESTABLISHED-已經(jīng)建立連接顿膨;
- 服務(wù)端這時(shí)候收到了來(lái)自客戶(hù)端的報(bào)文锅锨,服務(wù)端需要確認(rèn)客戶(hù)端收到了自己發(fā)送的消息,所以會(huì)看報(bào)文中的ack是否就是自己的序列號(hào)(seq)+1虽惭,如果一切滿(mǎn)足條件橡类,那就將自己的狀態(tài)置為ESTABLISHED-已經(jīng)建立連接;
至此芽唇,客戶(hù)端和服務(wù)端經(jīng)歷了三次握手后,連接就已經(jīng)建立成功了取劫,雙方可以互相進(jìn)行通訊了匆笤。
TCP的四次揮手
說(shuō)明一下,三次握手谱邪,一般來(lái)說(shuō)是客戶(hù)端發(fā)起炮捧,但是四次揮手有客戶(hù)端和服務(wù)端都有可能發(fā)起,所以在此惦银,我們的兩個(gè)設(shè)備我寫(xiě)成了端1和端2咆课,假定現(xiàn)在是由端1發(fā)起揮手末誓。
- 端1發(fā)起揮手,告訴端2书蚪,我想跟你斷開(kāi)連接喇澡,然后端1就不再往端2發(fā)送數(shù)據(jù)了,端1傳給端2自己的序列號(hào)seq = J殊校,同時(shí)將自己的狀態(tài)置為FIN_WAIT_1晴玖;
- 端2收到了端1的報(bào)文,就告訴端1为流,好的呕屎,我收到了你斷開(kāi)的請(qǐng)求了,于是給端1發(fā)送了確認(rèn)的報(bào)文(就是將端1的序列號(hào)+1)然后返給端1敬察,將自己的狀態(tài)置為關(guān)閉等待(CLOSE_WAIT)秀睛;
- 這個(gè)時(shí)候只是給端1發(fā)送了個(gè)確認(rèn)消息,還沒(méi)有發(fā)送斷開(kāi)的消息莲祸,所以下一步端2會(huì)給端1發(fā)送斷開(kāi)的報(bào)文蹂安,同時(shí)傳入自己的序列號(hào),將自己的狀態(tài)置為了LAST_ACK虫给,表示自己準(zhǔn)備好了接收最后一個(gè)確認(rèn)報(bào)文藤抡;
- 端1會(huì)首先接收到端2的確認(rèn)報(bào)文,然后會(huì)將自己的狀態(tài)置為FIN_WAIT_2抹估,然后再接收到了端2的斷開(kāi)報(bào)文缠黍,會(huì)返回給端2自己已經(jīng)收到了你斷開(kāi)的報(bào)文(將端2的序列號(hào)+1并賦值給ack返回),同時(shí)會(huì)將自己的狀態(tài)置為T(mén)IME_WAIT药蜻,在等待了2MSL的時(shí)間后瓷式,會(huì)將自己關(guān)閉。
- 端2收到了端1的報(bào)文后语泽,會(huì)將自己關(guān)閉贸典。
至此整個(gè)的四次揮手就完成了。在此說(shuō)明一下為什么端1需要等待2MSL踱卵,原因有2個(gè):
- 在端1發(fā)送的最后一次確認(rèn)報(bào)文是有可能丟失的廊驼,如果丟失需要讓端2重傳一個(gè)FIN報(bào)文過(guò)來(lái)。
- 是因?yàn)閳?bào)文的存活時(shí)間是1MSL惋砂,ACK從端1發(fā)送到端2最多只需要1MSL妒挎,當(dāng)丟失了,端2發(fā)給端1的重傳報(bào)文最多也只有1MSL西饵,所以如果端2重發(fā)了酝掩,最多只要經(jīng)過(guò)2MSL。
至此三次握手和四次揮手就講完了眷柔,如果有不對(duì)的地方歡迎評(píng)論區(qū)里留言期虾。