2020年最新網(wǎng)絡(luò)編程面試題
計(jì)算機(jī)網(wǎng)絡(luò)體系結(jié)構(gòu)
在計(jì)算機(jī)網(wǎng)絡(luò)的基本概念中,分層次的體系結(jié)構(gòu)是最基本的。計(jì)算機(jī)網(wǎng)絡(luò)體系結(jié)構(gòu)的抽象概念較多,在學(xué)習(xí)時(shí)要多思考。這些概念對(duì)后面的學(xué)習(xí)很有幫助。
網(wǎng)絡(luò)協(xié)議是什么?
在計(jì)算機(jī)網(wǎng)絡(luò)要做到有條不紊地交換數(shù)據(jù),就必須遵守一些事先約定好的規(guī)則,比如交換數(shù)據(jù)的格式、是否需要發(fā)送一個(gè)應(yīng)答信息。這些規(guī)則被稱為網(wǎng)絡(luò)協(xié)議。
為什么要對(duì)網(wǎng)絡(luò)協(xié)議分層?
簡(jiǎn)化問(wèn)題難度和復(fù)雜度。由于各層之間獨(dú)立,我們可以分割大問(wèn)題為小問(wèn)題。 靈活性好。當(dāng)其中一層的技術(shù)變化時(shí),只要層間接口關(guān)系保持不變,其他層不受影響。 易于實(shí)現(xiàn)和維護(hù)。 促進(jìn)標(biāo)準(zhǔn)化工作。分開后,每層功能可以相對(duì)簡(jiǎn)單地被描述。
網(wǎng)絡(luò)協(xié)議分層的缺點(diǎn):功能可能出現(xiàn)在多個(gè)層里,產(chǎn)生了額外開銷。
為了使不同體系結(jié)構(gòu)的計(jì)算機(jī)網(wǎng)絡(luò)都能互聯(lián),國(guó)際標(biāo)準(zhǔn)化組織 ISO 于1977年提出了一個(gè)試圖使各種計(jì)算機(jī)在世界范圍內(nèi)互聯(lián)成網(wǎng)的標(biāo)準(zhǔn)框架,即著名的開放系統(tǒng)互聯(lián)基本參考模型 OSI/RM,簡(jiǎn)稱為OSI。
OSI 的七層協(xié)議體系結(jié)構(gòu)的概念清楚,理論也較完整,但它既復(fù)雜又不實(shí)用,TCP/IP 體系結(jié)構(gòu)則不同,但它現(xiàn)在卻得到了非常廣泛的應(yīng)用。TCP/IP 是一個(gè)四層體系結(jié)構(gòu),它包含應(yīng)用層,運(yùn)輸層,網(wǎng)際層和網(wǎng)絡(luò)接口層(用網(wǎng)際層這個(gè)名字是強(qiáng)調(diào)這一層是為了解決不同網(wǎng)絡(luò)的互連問(wèn)題),不過(guò)從實(shí)質(zhì)上講,TCP/IP 只有最上面的三層,因?yàn)樽钕旅娴木W(wǎng)絡(luò)接口層并沒(méi)有什么具體內(nèi)容,因此在學(xué)習(xí)計(jì)算機(jī)網(wǎng)絡(luò)的原理時(shí)往往采用折中的辦法,即綜合 OSI 和 TCP/IP 的優(yōu)點(diǎn),采用一種只有五層協(xié)議的體系結(jié)構(gòu),這樣既簡(jiǎn)潔又能將概念闡述清楚,有時(shí)為了方便,也可把最底下兩層稱為網(wǎng)絡(luò)接口層。
四層協(xié)議,五層協(xié)議和七層協(xié)議的關(guān)系如下:
TCP/IP是一個(gè)四層的體系結(jié)構(gòu),主要包括:應(yīng)用層、運(yùn)輸層、網(wǎng)際層和網(wǎng)絡(luò)接口層。 五層協(xié)議的體系結(jié)構(gòu)主要包括:應(yīng)用層、運(yùn)輸層、網(wǎng)絡(luò)層,數(shù)據(jù)鏈路層和物理層。 OSI七層協(xié)議模型主要包括是:應(yīng)用層(Application)、表示層(Presentation)、會(huì)話層(Session)、運(yùn)輸層(Transport)、網(wǎng)絡(luò)層(Network)、數(shù)據(jù)鏈路層(Data Link)、物理層(Physical)。

注:五層協(xié)議的體系結(jié)構(gòu)只是為了介紹網(wǎng)絡(luò)原理而設(shè)計(jì)的,實(shí)際應(yīng)用還是 TCP/IP 四層體系結(jié)構(gòu)。
TCP/IP 協(xié)議族
應(yīng)用層
應(yīng)用層( application-layer )的任務(wù)是通過(guò)應(yīng)用進(jìn)程間的交互來(lái)完成特定網(wǎng)絡(luò)應(yīng)用。應(yīng)用層協(xié)議定義的是應(yīng)用進(jìn)程(進(jìn)程:主機(jī)中正在運(yùn)行的程序)間的通信和交互的規(guī)則。
對(duì)于不同的網(wǎng)絡(luò)應(yīng)用需要不同的應(yīng)用層協(xié)議。在互聯(lián)網(wǎng)中應(yīng)用層協(xié)議很多,如域名系統(tǒng) DNS,支持萬(wàn)維網(wǎng)應(yīng)用的 HTTP 協(xié)議,支持電子郵件的 SMTP 協(xié)議等等。
運(yùn)輸層
運(yùn)輸層(transport layer)的主要任務(wù)就是負(fù)責(zé)向兩臺(tái)主機(jī)進(jìn)程之間的通信提供通用的數(shù)據(jù)傳輸服務(wù)。應(yīng)用進(jìn)程利用該服務(wù)傳送應(yīng)用層報(bào)文。
運(yùn)輸層主要使用一下兩種協(xié)議
傳輸控制協(xié)議-TCP:提供面向連接的,可靠的數(shù)據(jù)傳輸服務(wù)。 用戶數(shù)據(jù)協(xié)議-UDP:提供無(wú)連接的,盡最大努力的數(shù)據(jù)傳輸服務(wù)(不保證數(shù)據(jù)傳輸?shù)目煽啃裕?/section>
| UDP | TCP | |
|---|---|---|
| 是否連接 | 無(wú)連接 | 面向連接 |
| 是否可靠 | 不可靠傳輸,不使用流量控制和擁塞控制 | 可靠傳輸,使用流量控制和擁塞控制 |
| 連接對(duì)象個(gè)數(shù) | 支持一對(duì)一,一對(duì)多,多對(duì)一和多對(duì)多交互通信 | 只能是一對(duì)一通信 |
| 傳輸方式 | 面向報(bào)文 | 面向字節(jié)流 |
| 首部開銷 | 首部開銷小,僅8字節(jié) | 首部最小20字節(jié),最大60字節(jié) |
| 場(chǎng)景 | 適用于實(shí)時(shí)應(yīng)用(IP電話、視頻會(huì)議、直播等) | 適用于要求可靠傳輸?shù)膽?yīng)用,例如文件傳輸 |
每一個(gè)應(yīng)用層(TCP/IP參考模型的最高層)協(xié)議一般都會(huì)使用到兩個(gè)傳輸層協(xié)議之一:
運(yùn)行在TCP協(xié)議上的協(xié)議:
HTTP(Hypertext Transfer Protocol,超文本傳輸協(xié)議),主要用于普通瀏覽。HTTPS(HTTP over SSL,安全超文本傳輸協(xié)議),HTTP協(xié)議的安全版本。FTP(File Transfer Protocol,文件傳輸協(xié)議),用于文件傳輸。POP3(Post Office Protocol, version 3,郵局協(xié)議),收郵件用。SMTP(Simple Mail Transfer Protocol,簡(jiǎn)單郵件傳輸協(xié)議),用來(lái)發(fā)送電子郵件。TELNET(Teletype over the Network,網(wǎng)絡(luò)電傳),通過(guò)一個(gè)終端(terminal)登陸到網(wǎng)絡(luò)。SSH(Secure Shell,用于替代安全性差的TELNET),用于加密安全登陸用。
運(yùn)行在UDP協(xié)議上的協(xié)議:
BOOTP(Boot Protocol,啟動(dòng)協(xié)議),應(yīng)用于無(wú)盤設(shè)備。NTP(Network Time Protocol,網(wǎng)絡(luò)時(shí)間協(xié)議),用于網(wǎng)絡(luò)同步。DHCP(Dynamic Host Configuration Protocol,動(dòng)態(tài)主機(jī)配置協(xié)議),動(dòng)態(tài)配置IP地址。
運(yùn)行在TCP和UDP協(xié)議上:
DNS(Domain Name Service,域名服務(wù)),用于完成地址查找,郵件轉(zhuǎn)發(fā)等工作。
網(wǎng)絡(luò)層
網(wǎng)絡(luò)層的任務(wù)就是選擇合適的網(wǎng)間路由和交換結(jié)點(diǎn),確保計(jì)算機(jī)通信的數(shù)據(jù)及時(shí)傳送。在發(fā)送數(shù)據(jù)時(shí),網(wǎng)絡(luò)層把運(yùn)輸層產(chǎn)生的報(bào)文段或用戶數(shù)據(jù)報(bào)封裝成分組和包進(jìn)行傳送。在 TCP/IP 體系結(jié)構(gòu)中,由于網(wǎng)絡(luò)層使用 IP 協(xié)議,因此分組也叫 IP 數(shù)據(jù)報(bào) ,簡(jiǎn)稱數(shù)據(jù)報(bào)。
互聯(lián)網(wǎng)是由大量的異構(gòu)(heterogeneous)網(wǎng)絡(luò)通過(guò)路由器(router)相互連接起來(lái)的?;ヂ?lián)網(wǎng)使用的網(wǎng)絡(luò)層協(xié)議是無(wú)連接的網(wǎng)際協(xié)議(Intert Prococol)和許多路由選擇協(xié)議,因此互聯(lián)網(wǎng)的網(wǎng)絡(luò)層也叫做網(wǎng)際層或 IP 層。
數(shù)據(jù)鏈路層
數(shù)據(jù)鏈路層(data link layer)通常簡(jiǎn)稱為鏈路層。兩臺(tái)主機(jī)之間的數(shù)據(jù)傳輸,總是在一段一段的鏈路上傳送的,這就需要使用專門的鏈路層的協(xié)議。
在兩個(gè)相鄰節(jié)點(diǎn)之間傳送數(shù)據(jù)時(shí),數(shù)據(jù)鏈路層將網(wǎng)絡(luò)層交下來(lái)的 IP 數(shù)據(jù)報(bào)組裝成幀,在兩個(gè)相鄰節(jié)點(diǎn)間的鏈路上傳送幀。每一幀包括數(shù)據(jù)和必要的控制信息(如同步信息,地址信息,差錯(cuò)控制等)。
在接收數(shù)據(jù)時(shí),控制信息使接收端能夠知道一個(gè)幀從哪個(gè)比特開始和到哪個(gè)比特結(jié)束。
一般的web應(yīng)用的通信傳輸流是這樣的:

發(fā)送端在層與層之間傳輸數(shù)據(jù)時(shí),每經(jīng)過(guò)一層時(shí)會(huì)被打上一個(gè)該層所屬的首部信息。反之,接收端在層與層之間傳輸數(shù)據(jù)時(shí),每經(jīng)過(guò)一層時(shí)會(huì)把對(duì)應(yīng)的首部信息去除。
物理層
在物理層上所傳送的數(shù)據(jù)單位是比特。物理層(physical layer)的作用是實(shí)現(xiàn)相鄰計(jì)算機(jī)節(jié)點(diǎn)之間比特流的透明傳送,盡可能屏蔽掉具體傳輸介質(zhì)和物理設(shè)備的差異。使其上面的數(shù)據(jù)鏈路層不必考慮網(wǎng)絡(luò)的具體傳輸介質(zhì)是什么?!巴该鱾魉捅忍亓鳌北硎窘?jīng)實(shí)際電路傳送后的比特流沒(méi)有發(fā)生變化,對(duì)傳送的比特流來(lái)說(shuō),這個(gè)電路好像是看不見的。
TCP/IP 協(xié)議族
在互聯(lián)網(wǎng)使用的各種協(xié)議中最重要和最著名的就是 TCP/IP 兩個(gè)協(xié)議?,F(xiàn)在人們經(jīng)常提到的 TCP/IP 并不一定是單指 TCP 和 IP 這兩個(gè)具體的協(xié)議,而往往是表示互聯(lián)網(wǎng)所使用的整個(gè) TCP/IP 協(xié)議族。

互聯(lián)網(wǎng)協(xié)議套件(英語(yǔ):Internet Protocol Suite,縮寫
IPS)是一個(gè)網(wǎng)絡(luò)通訊模型,以及一整個(gè)網(wǎng)絡(luò)傳輸協(xié)議家族,為網(wǎng)際網(wǎng)絡(luò)的基礎(chǔ)通訊架構(gòu)。它常被通稱為TCP/IP協(xié)議族(英語(yǔ):TCP/IP Protocol Suite,或TCP/IP Protocols),簡(jiǎn)稱TCP/IP。因?yàn)樵搮f(xié)定家族的兩個(gè)核心協(xié)定:TCP(傳輸控制協(xié)議)和IP(網(wǎng)際協(xié)議),為該家族中最早通過(guò)的標(biāo)準(zhǔn)。
劃重點(diǎn):
TCP(傳輸控制協(xié)議)和IP(網(wǎng)際協(xié)議)`?是最先定義的兩個(gè)核心協(xié)議,所以才統(tǒng)稱為`TCP/IP協(xié)議族
TCP的三次握手四次揮手
TCP是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議,在發(fā)送數(shù)據(jù)前,通信雙方必須在彼此間建立一條連接。所謂的“連接”,其實(shí)是客戶端和服務(wù)端保存的一份關(guān)于對(duì)方的信息,如ip地址、端口號(hào)等。
TCP可以看成是一種字節(jié)流,它會(huì)處理IP層或以下的層的丟包、重復(fù)以及錯(cuò)誤問(wèn)題。在連接的建立過(guò)程中,雙方需要交換一些連接的參數(shù)。這些參數(shù)可以放在TCP頭部。
一個(gè)TCP連接由一個(gè)4元組構(gòu)成,分別是兩個(gè)IP地址和兩個(gè)端口號(hào)。一個(gè)TCP連接通常分為三個(gè)階段:連接、數(shù)據(jù)傳輸、退出(關(guān)閉)。通過(guò)三次握手建立一個(gè)鏈接,通過(guò)四次揮手來(lái)關(guān)閉一個(gè)連接。
當(dāng)一個(gè)連接被建立或被終止時(shí),交換的報(bào)文段只包含TCP頭部,而沒(méi)有數(shù)據(jù)。
TCP報(bào)文的頭部結(jié)構(gòu)
在了解TCP連接之前先來(lái)了解一下TCP報(bào)文的頭部結(jié)構(gòu)。

上圖中有幾個(gè)字段需要重點(diǎn)介紹下:
(1)序號(hào):seq序號(hào),占32位,用來(lái)標(biāo)識(shí)從TCP源端向目的端發(fā)送的字節(jié)流,發(fā)起方發(fā)送數(shù)據(jù)時(shí)對(duì)此進(jìn)行標(biāo)記。
(2)確認(rèn)序號(hào):ack序號(hào),占32位,只有ACK標(biāo)志位為1時(shí),確認(rèn)序號(hào)字段才有效,ack=seq+1。
(3)標(biāo)志位:共6個(gè),即URG、ACK、PSH、RST、SYN、FIN等,具體含義如下:
ACK:確認(rèn)序號(hào)有效。 FIN:釋放一個(gè)連接。 PSH:接收方應(yīng)該盡快將這個(gè)報(bào)文交給應(yīng)用層。 RST:重置連接。 SYN:發(fā)起一個(gè)新連接。 URG:緊急指針(urgent pointer)有效。
需要注意的是:
不要將確認(rèn)序號(hào)ack與標(biāo)志位中的ACK搞混了。 確認(rèn)方ack=發(fā)起方seq+1,兩端配對(duì)。
三次握手
三次握手的本質(zhì)是確認(rèn)通信雙方收發(fā)數(shù)據(jù)的能力
首先,我讓信使運(yùn)輸一份信件給對(duì)方,對(duì)方收到了,那么他就知道了我的發(fā)件能力和他的收件能力是可以的。
于是他給我回信,我若收到了,我便知我的發(fā)件能力和他的收件能力是可以的,并且他的發(fā)件能力和我的收件能力是可以。
然而此時(shí)他還不知道他的發(fā)件能力和我的收件能力到底可不可以,于是我最后回饋一次,他若收到了,他便清楚了他的發(fā)件能力和我的收件能力是可以的。
這,就是三次握手,這樣說(shuō),你理解了嗎?

第一次握手:客戶端要向服務(wù)端發(fā)起連接請(qǐng)求,首先客戶端隨機(jī)生成一個(gè)起始序列號(hào)ISN(比如是100),那客戶端向服務(wù)端發(fā)送的報(bào)文段包含SYN標(biāo)志位(也就是SYN=1),序列號(hào)seq=100。第二次握手:服務(wù)端收到客戶端發(fā)過(guò)來(lái)的報(bào)文后,發(fā)現(xiàn)SYN=1,知道這是一個(gè)連接請(qǐng)求,于是將客戶端的起始序列號(hào)100存起來(lái),并且隨機(jī)生成一個(gè)服務(wù)端的起始序列號(hào)(比如是300)。然后給客戶端回復(fù)一段報(bào)文,回復(fù)報(bào)文包含SYN和ACK標(biāo)志(也就是SYN=1,ACK=1)、序列號(hào)seq=300、確認(rèn)號(hào)ack=101(客戶端發(fā)過(guò)來(lái)的序列號(hào)+1)。第三次握手:客戶端收到服務(wù)端的回復(fù)后發(fā)現(xiàn)ACK=1并且ack=101,于是知道服務(wù)端已經(jīng)收到了序列號(hào)為100的那段報(bào)文;同時(shí)發(fā)現(xiàn)SYN=1,知道了服務(wù)端同意了這次連接,于是就將服務(wù)端的序列號(hào)300給存下來(lái)。然后客戶端再回復(fù)一段報(bào)文給服務(wù)端,報(bào)文包含ACK標(biāo)志位(ACK=1)、ack=301(服務(wù)端序列號(hào)+1)、seq=101(第一次握手時(shí)發(fā)送報(bào)文是占據(jù)一個(gè)序列號(hào)的,所以這次seq就從101開始,需要注意的是不攜帶數(shù)據(jù)的ACK報(bào)文是不占據(jù)序列號(hào)的,所以后面第一次正式發(fā)送數(shù)據(jù)時(shí)seq還是101)。當(dāng)服務(wù)端收到報(bào)文后發(fā)現(xiàn)ACK=1并且ack=301,就知道客戶端收到序列號(hào)為300的報(bào)文了,就這樣客戶端和服務(wù)端通過(guò)TCP建立了連接。
四次揮手
四次揮手的目的是關(guān)閉一個(gè)連接

比如客戶端初始化的序列號(hào)ISA=100,服務(wù)端初始化的序列號(hào)ISA=300。TCP連接成功后客戶端總共發(fā)送了1000個(gè)字節(jié)的數(shù)據(jù),服務(wù)端在客戶端發(fā)FIN報(bào)文前總共回復(fù)了2000個(gè)字節(jié)的數(shù)據(jù)。
第一次揮手:當(dāng)客戶端的數(shù)據(jù)都傳輸完成后,客戶端向服務(wù)端發(fā)出連接釋放報(bào)文(當(dāng)然數(shù)據(jù)沒(méi)發(fā)完時(shí)也可以發(fā)送連接釋放報(bào)文并停止發(fā)送數(shù)據(jù)),釋放連接報(bào)文包含F(xiàn)IN標(biāo)志位(FIN=1)、序列號(hào)seq=1101(100+1+1000,其中的1是建立連接時(shí)占的一個(gè)序列號(hào))。需要注意的是客戶端發(fā)出FIN報(bào)文段后只是不能發(fā)數(shù)據(jù)了,但是還可以正常收數(shù)據(jù);另外FIN報(bào)文段即使不攜帶數(shù)據(jù)也要占據(jù)一個(gè)序列號(hào)。第二次揮手:服務(wù)端收到客戶端發(fā)的FIN報(bào)文后給客戶端回復(fù)確認(rèn)報(bào)文,確認(rèn)報(bào)文包含ACK標(biāo)志位(ACK=1)、確認(rèn)號(hào)ack=1102(客戶端FIN報(bào)文序列號(hào)1101+1)、序列號(hào)seq=2300(300+2000)。此時(shí)服務(wù)端處于關(guān)閉等待狀態(tài),而不是立馬給客戶端發(fā)FIN報(bào)文,這個(gè)狀態(tài)還要持續(xù)一段時(shí)間,因?yàn)榉?wù)端可能還有數(shù)據(jù)沒(méi)發(fā)完。第三次揮手:服務(wù)端將最后數(shù)據(jù)(比如50個(gè)字節(jié))發(fā)送完畢后就向客戶端發(fā)出連接釋放報(bào)文,報(bào)文包含F(xiàn)IN和ACK標(biāo)志位(FIN=1,ACK=1)、確認(rèn)號(hào)和第二次揮手一樣ack=1102、序列號(hào)seq=2350(2300+50)。第四次揮手:客戶端收到服務(wù)端發(fā)的FIN報(bào)文后,向服務(wù)端發(fā)出確認(rèn)報(bào)文,確認(rèn)報(bào)文包含ACK標(biāo)志位(ACK=1)、確認(rèn)號(hào)ack=2351、序列號(hào)seq=1102。注意客戶端發(fā)出確認(rèn)報(bào)文后不是立馬釋放TCP連接,而是要經(jīng)過(guò)2MSL(最長(zhǎng)報(bào)文段壽命的2倍時(shí)長(zhǎng))后才釋放TCP連接。而服務(wù)端一旦收到客戶端發(fā)出的確認(rèn)報(bào)文就會(huì)立馬釋放TCP連接,所以服務(wù)端結(jié)束TCP連接的時(shí)間要比客戶端早一些。
常見面試題
為什么TCP連接的時(shí)候是3次?2次不可以嗎?
因?yàn)樾枰紤]連接時(shí)丟包的問(wèn)題,如果只握手2次,第二次握手時(shí)如果服務(wù)端發(fā)給客戶端的確認(rèn)報(bào)文段丟失,此時(shí)服務(wù)端已經(jīng)準(zhǔn)備好了收發(fā)數(shù)(可以理解服務(wù)端已經(jīng)連接成功)據(jù),而客戶端一直沒(méi)收到服務(wù)端的確認(rèn)報(bào)文,所以客戶端就不知道服務(wù)端是否已經(jīng)準(zhǔn)備好了(可以理解為客戶端未連接成功),這種情況下客戶端不會(huì)給服務(wù)端發(fā)數(shù)據(jù),也會(huì)忽略服務(wù)端發(fā)過(guò)來(lái)的數(shù)據(jù)。
如果是三次握手,即便發(fā)生丟包也不會(huì)有問(wèn)題,比如如果第三次握手客戶端發(fā)的確認(rèn)ack報(bào)文丟失,服務(wù)端在一段時(shí)間內(nèi)沒(méi)有收到確認(rèn)ack報(bào)文的話就會(huì)重新進(jìn)行第二次握手,也就是服務(wù)端會(huì)重發(fā)SYN報(bào)文段,客戶端收到重發(fā)的報(bào)文段后會(huì)再次給服務(wù)端發(fā)送確認(rèn)ack報(bào)文。
為什么TCP連接的時(shí)候是3次,關(guān)閉的時(shí)候卻是4次?
因?yàn)橹挥性诳蛻舳撕头?wù)端都沒(méi)有數(shù)據(jù)要發(fā)送的時(shí)候才能斷開TCP。而客戶端發(fā)出FIN報(bào)文時(shí)只能保證客戶端沒(méi)有數(shù)據(jù)發(fā)了,服務(wù)端還有沒(méi)有數(shù)據(jù)發(fā)客戶端是不知道的。而服務(wù)端收到客戶端的FIN報(bào)文后只能先回復(fù)客戶端一個(gè)確認(rèn)報(bào)文來(lái)告訴客戶端我服務(wù)端已經(jīng)收到你的FIN報(bào)文了,但我服務(wù)端還有一些數(shù)據(jù)沒(méi)發(fā)完,等這些數(shù)據(jù)發(fā)完了服務(wù)端才能給客戶端發(fā)FIN報(bào)文(所以不能一次性將確認(rèn)報(bào)文和FIN報(bào)文發(fā)給客戶端,就是這里多出來(lái)了一次)。
為什么客戶端發(fā)出第四次揮手的確認(rèn)報(bào)文后要等2MSL的時(shí)間才能釋放TCP連接?
這里同樣是要考慮丟包的問(wèn)題,如果第四次揮手的報(bào)文丟失,服務(wù)端沒(méi)收到確認(rèn)ack報(bào)文就會(huì)重發(fā)第三次揮手的報(bào)文,這樣報(bào)文一去一回最長(zhǎng)時(shí)間就是2MSL,所以需要等這么長(zhǎng)時(shí)間來(lái)確認(rèn)服務(wù)端確實(shí)已經(jīng)收到了。
如果已經(jīng)建立了連接,但是客戶端突然出現(xiàn)故障了怎么辦?
TCP設(shè)有一個(gè)?;钣?jì)時(shí)器,客戶端如果出現(xiàn)故障,服務(wù)器不能一直等下去,白白浪費(fèi)資源。服務(wù)器每收到一次客戶端的請(qǐng)求后都會(huì)重新復(fù)位這個(gè)計(jì)時(shí)器,時(shí)間通常是設(shè)置為2小時(shí),若兩小時(shí)還沒(méi)有收到客戶端的任何數(shù)據(jù),服務(wù)器就會(huì)發(fā)送一個(gè)探測(cè)報(bào)文段,以后每隔75秒鐘發(fā)送一次。若一連發(fā)送10個(gè)探測(cè)報(bào)文仍然沒(méi)反應(yīng),服務(wù)器就認(rèn)為客戶端出了故障,接著就關(guān)閉連接。
什么是HTTP,HTTP 與 HTTPS 的區(qū)別
HTTP 是一個(gè)在計(jì)算機(jī)世界里專門在兩點(diǎn)之間傳輸文字、圖片、音頻、視頻等超文本數(shù)據(jù)的約定和規(guī)范
| 區(qū)別 | HTTP | HTTPS |
|---|---|---|
| 協(xié)議 | 運(yùn)行在 TCP 之上,明文傳輸,客戶端與服務(wù)器端都無(wú)法驗(yàn)證對(duì)方的身份 | 身披 SSL( Secure Socket Layer )外殼的 HTTP,運(yùn)行于 SSL 上,SSL 運(yùn)行于 TCP 之上,?是添加了加密和認(rèn)證機(jī)制的 HTTP。 |
| 端口 | 80 | 443 |
| 資源消耗 | 較少 | 由于加解密處理,會(huì)消耗更多的 CPU 和內(nèi)存資源 |
| 開銷 | 無(wú)需證書 | 需要證書,而證書一般需要向認(rèn)證機(jī)構(gòu)購(gòu)買 |
| 加密機(jī)制 | 無(wú) | 共享密鑰加密和公開密鑰加密并用的混合加密機(jī)制 |
| 安全性 | 弱 | 由于加密機(jī)制,安全性強(qiáng) |
常用HTTP狀態(tài)碼
HTTP狀態(tài)碼表示客戶端HTTP請(qǐng)求的返回結(jié)果、標(biāo)識(shí)服務(wù)器處理是否正常、表明請(qǐng)求出現(xiàn)的錯(cuò)誤等。
狀態(tài)碼的類別:
| 類別 | 原因短語(yǔ) |
|---|---|
| 1XX | Informational(信息性狀態(tài)碼) 接受的請(qǐng)求正在處理 |
| 2XX | Success(成功狀態(tài)碼) 請(qǐng)求正常處理完畢 |
| 3XX | Redirection(重定向狀態(tài)碼) 需要進(jìn)行附加操作以完成請(qǐng)求 |
| 4XX | Client Error(客戶端錯(cuò)誤狀態(tài)碼) 服務(wù)器無(wú)法處理請(qǐng)求 |
| 5XX | Server Error(服務(wù)器錯(cuò)誤狀態(tài)碼) 服務(wù)器處理請(qǐng)求出錯(cuò) |
常用HTTP狀態(tài)碼:
| 2XX | 成功(這系列表明請(qǐng)求被正常處理了) |
|---|---|
| 200 | OK,表示從客戶端發(fā)來(lái)的請(qǐng)求在服務(wù)器端被正確處理 |
| 204 | No content,表示請(qǐng)求成功,但響應(yīng)報(bào)文不含實(shí)體的主體部分 |
| 206 | Partial Content,進(jìn)行范圍請(qǐng)求成功 |
| 3XX | 重定向(表明瀏覽器要執(zhí)行特殊處理) |
|---|---|
| 301 | moved permanently,永久性重定向,表示資源已被分配了新的 URL |
| 302 | found,臨時(shí)性重定向,表示資源臨時(shí)被分配了新的 URL |
| 303 | see other,表示資源存在著另一個(gè) URL,應(yīng)使用 GET 方法獲取資源(對(duì)于301/302/303響應(yīng),幾乎所有瀏覽器都會(huì)刪除報(bào)文主體并自動(dòng)用GET重新請(qǐng)求) |
| 304 | not modified,表示服務(wù)器允許訪問(wèn)資源,但請(qǐng)求未滿足條件的情況(與重定向無(wú)關(guān)) |
| 307 | temporary redirect,臨時(shí)重定向,和302含義類似,但是期望客戶端保持請(qǐng)求方法不變向新的地址發(fā)出請(qǐng)求 |
| 4XX | 客戶端錯(cuò)誤 |
|---|---|
| 400 | bad request,請(qǐng)求報(bào)文存在語(yǔ)法錯(cuò)誤 |
| 401 | unauthorized,表示發(fā)送的請(qǐng)求需要有通過(guò) HTTP 認(rèn)證的認(rèn)證信息 |
| 403 | forbidden,表示對(duì)請(qǐng)求資源的訪問(wèn)被服務(wù)器拒絕,可在實(shí)體主體部分返回原因描述 |
| 404 | not found,表示在服務(wù)器上沒(méi)有找到請(qǐng)求的資源 |
| 5XX | 服務(wù)器錯(cuò)誤 |
|---|---|
| 500 | internal sever error,表示服務(wù)器端在執(zhí)行請(qǐng)求時(shí)發(fā)生了錯(cuò)誤 |
| 501 | Not Implemented,表示服務(wù)器不支持當(dāng)前請(qǐng)求所需要的某個(gè)功能 |
| 503 | service unavailable,表明服務(wù)器暫時(shí)處于超負(fù)載或正在停機(jī)維護(hù),無(wú)法處理請(qǐng)求 |
GET和POST區(qū)別
說(shuō)道GET和POST,就不得不提HTTP協(xié)議,因?yàn)闉g覽器和服務(wù)器的交互是通過(guò)HTTP協(xié)議執(zhí)行的,而GET和POST也是HTTP協(xié)議中的兩種方法。
HTTP全稱為Hyper Text Transfer Protocol,中文翻譯為超文本傳輸協(xié)議,目的是保證瀏覽器與服務(wù)器之間的通信。HTTP的工作方式是客戶端與服務(wù)器之間的請(qǐng)求-應(yīng)答協(xié)議。
HTTP協(xié)議中定義了瀏覽器和服務(wù)器進(jìn)行交互的不同方法,基本方法有4種,分別是GET,POST,PUT,DELETE。這四種方法可以理解為,對(duì)服務(wù)器資源的查,改,增,刪。
GET:從服務(wù)器上獲取數(shù)據(jù),也就是所謂的查,僅僅是獲取服務(wù)器資源,不進(jìn)行修改。 POST:向服務(wù)器提交數(shù)據(jù),這就涉及到了數(shù)據(jù)的更新,也就是更改服務(wù)器的數(shù)據(jù)。 PUT:英文含義是放置,也就是向服務(wù)器新添加數(shù)據(jù),就是所謂的增。 DELETE:從字面意思也能看出,這種方式就是刪除服務(wù)器數(shù)據(jù)的過(guò)程。
GET和POST區(qū)別
Get是不安全的,因?yàn)樵趥鬏斶^(guò)程,數(shù)據(jù)被放在請(qǐng)求的URL中;Post的所有操作對(duì)用戶來(lái)說(shuō)都是不可見的。但是這種做法也不時(shí)絕對(duì)的,大部分人的做法也是按照上面的說(shuō)法來(lái)的,但是也可以在get請(qǐng)求加上 request body,給 post請(qǐng)求帶上 URL 參數(shù)。
Get請(qǐng)求提交的url中的數(shù)據(jù)最多只能是2048字節(jié),這個(gè)限制是瀏覽器或者服務(wù)器給添加的,http協(xié)議并沒(méi)有對(duì)url長(zhǎng)度進(jìn)行限制,目的是為了保證服務(wù)器和瀏覽器能夠正常運(yùn)行,防止有人惡意發(fā)送請(qǐng)求。Post請(qǐng)求則沒(méi)有大小限制。
Get限制Form表單的數(shù)據(jù)集的值必須為ASCII字符;而Post支持整個(gè)ISO10646字符集。
Get執(zhí)行效率卻比Post方法好。Get是form提交的默認(rèn)方法。
GET產(chǎn)生一個(gè)TCP數(shù)據(jù)包;POST產(chǎn)生兩個(gè)TCP數(shù)據(jù)包。
對(duì)于GET方式的請(qǐng)求,瀏覽器會(huì)把http header和data一并發(fā)送出去,服務(wù)器響應(yīng)200(返回?cái)?shù)據(jù));
而對(duì)于POST,瀏覽器先發(fā)送header,服務(wù)器響應(yīng)100 continue,瀏覽器再發(fā)送data,服務(wù)器響應(yīng)200 ok(返回?cái)?shù)據(jù))。
什么是對(duì)稱加密與非對(duì)稱加密
對(duì)稱密鑰加密是指加密和解密使用同一個(gè)密鑰的方式,這種方式存在的最大問(wèn)題就是密鑰發(fā)送問(wèn)題,即如何安全地將密鑰發(fā)給對(duì)方;
而非對(duì)稱加密是指使用一對(duì)非對(duì)稱密鑰,即公鑰和私鑰,公鑰可以隨意發(fā)布,但私鑰只有自己知道。發(fā)送密文的一方使用對(duì)方的公鑰進(jìn)行加密處理,對(duì)方接收到加密信息后,使用自己的私鑰進(jìn)行解密。由于非對(duì)稱加密的方式不需要發(fā)送用來(lái)解密的私鑰,所以可以保證安全性;但是和對(duì)稱加密比起來(lái),非常的慢
什么是HTTP2
HTTP2 可以提高了網(wǎng)頁(yè)的性能。
在 HTTP1 中瀏覽器限制了同一個(gè)域名下的請(qǐng)求數(shù)量(Chrome 下一般是六個(gè)),當(dāng)在請(qǐng)求很多資源的時(shí)候,由于隊(duì)頭阻塞當(dāng)瀏覽器達(dá)到最大請(qǐng)求數(shù)量時(shí),剩余的資源需等待當(dāng)前的六個(gè)請(qǐng)求完成后才能發(fā)起請(qǐng)求。
HTTP2 中引入了多路復(fù)用的技術(shù),這個(gè)技術(shù)可以只通過(guò)一個(gè) TCP 連接就可以傳輸所有的請(qǐng)求數(shù)據(jù)。多路復(fù)用可以繞過(guò)瀏覽器限制同一個(gè)域名下的請(qǐng)求數(shù)量的問(wèn)題,進(jìn)而提高了網(wǎng)頁(yè)的性能。
Session、Cookie和Token的主要區(qū)別
HTTP協(xié)議本身是無(wú)狀態(tài)的。什么是無(wú)狀態(tài)呢,即服務(wù)器無(wú)法判斷用戶身份。
什么是cookie
cookie是由Web服務(wù)器保存在用戶瀏覽器上的小文件(key-value格式),包含用戶相關(guān)的信息??蛻舳讼蚍?wù)器發(fā)起請(qǐng)求,如果服務(wù)器需要記錄該用戶狀態(tài),就使用response向客戶端瀏覽器頒發(fā)一個(gè)Cookie??蛻舳藶g覽器會(huì)把Cookie保存起來(lái)。當(dāng)瀏覽器再請(qǐng)求該網(wǎng)站時(shí),瀏覽器把請(qǐng)求的網(wǎng)址連同該Cookie一同提交給服務(wù)器。服務(wù)器檢查該Cookie,以此來(lái)辨認(rèn)用戶身份。
什么是session
session是依賴Cookie實(shí)現(xiàn)的。session是服務(wù)器端對(duì)象
session 是瀏覽器和服務(wù)器會(huì)話過(guò)程中,服務(wù)器分配的一塊儲(chǔ)存空間。服務(wù)器默認(rèn)為瀏覽器在cookie中設(shè)置 sessionid,瀏覽器在向服務(wù)器請(qǐng)求過(guò)程中傳輸 cookie 包含 sessionid ,服務(wù)器根據(jù) sessionid 獲取出會(huì)話中存儲(chǔ)的信息,然后確定會(huì)話的身份信息。
cookie與session區(qū)別
存儲(chǔ)位置與安全性:cookie數(shù)據(jù)存放在客戶端上,安全性較差,session數(shù)據(jù)放在服務(wù)器上,安全性相對(duì)更高; 存儲(chǔ)空間:?jiǎn)蝹€(gè)cookie保存的數(shù)據(jù)不能超過(guò)4K,很多瀏覽器都限制一個(gè)站點(diǎn)最多保存20個(gè)cookie,session無(wú)此限制 占用服務(wù)器資源:session一定時(shí)間內(nèi)保存在服務(wù)器上,當(dāng)訪問(wèn)增多,占用服務(wù)器性能,考慮到服務(wù)器性能方面,應(yīng)當(dāng)使用cookie。
什么是Token
Token的引入:Token是在客戶端頻繁向服務(wù)端請(qǐng)求數(shù)據(jù),服務(wù)端頻繁的去數(shù)據(jù)庫(kù)查詢用戶名和密碼并進(jìn)行對(duì)比,判斷用戶名和密碼正確與否,并作出相應(yīng)提示,在這樣的背景下,Token便應(yīng)運(yùn)而生。
Token的定義:Token是服務(wù)端生成的一串字符串,以作客戶端進(jìn)行請(qǐng)求的一個(gè)令牌,當(dāng)?shù)谝淮蔚卿浐?,服?wù)器生成一個(gè)Token便將此Token返回給客戶端,以后客戶端只需帶上這個(gè)Token前來(lái)請(qǐng)求數(shù)據(jù)即可,無(wú)需再次帶上用戶名和密碼。
使用Token的目的:Token的目的是為了減輕服務(wù)器的壓力,減少頻繁的查詢數(shù)據(jù)庫(kù),使服務(wù)器更加健壯。
Token 是在服務(wù)端產(chǎn)生的。如果前端使用用戶名/密碼向服務(wù)端請(qǐng)求認(rèn)證,服務(wù)端認(rèn)證成功,那么在服務(wù)端會(huì)返回 Token 給前端。前端可以在每次請(qǐng)求的時(shí)候帶上 Token 證明自己的合法地位
session與token區(qū)別
session機(jī)制存在服務(wù)器壓力增大,CSRF跨站偽造請(qǐng)求攻擊,擴(kuò)展性不強(qiáng)等問(wèn)題; session存儲(chǔ)在服務(wù)器端,token存儲(chǔ)在客戶端 token提供認(rèn)證和授權(quán)功能,作為身份認(rèn)證,token安全性比session好; session這種會(huì)話存儲(chǔ)方式方式只適用于客戶端代碼和服務(wù)端代碼運(yùn)行在同一臺(tái)服務(wù)器上,token適用于項(xiàng)目級(jí)的前后端分離(前后端代碼運(yùn)行在不同的服務(wù)器下)
Servlet是線程安全的嗎
Servlet不是線程安全的,多線程并發(fā)的讀寫會(huì)導(dǎo)致數(shù)據(jù)不同步的問(wèn)題。
解決的辦法是盡量不要定義name屬性,而是要把name變量分別定義在doGet()和doPost()方法內(nèi)。雖然使用synchronized(name){}語(yǔ)句塊可以解決問(wèn)題,但是會(huì)造成線程的等待,不是很科學(xué)的辦法。
注意:多線程的并發(fā)的讀寫Servlet類屬性會(huì)導(dǎo)致數(shù)據(jù)不同步。但是如果只是并發(fā)地讀取屬性而不寫入,則不存在數(shù)據(jù)不同步的問(wèn)題。因此Servlet里的只讀屬性最好定義為final類型的。
Servlet接口中有哪些方法及Servlet生命周期探秘
在Java Web程序中,Servlet主要負(fù)責(zé)接收用戶請(qǐng)求HttpServletRequest,在doGet(),doPost()**中做相應(yīng)的處理,并將回應(yīng)**HttpServletResponse反饋給用戶。Servlet可以設(shè)置初始化參數(shù),供Servlet內(nèi)部使用。
Servlet接口定義了5個(gè)方法,其中前三個(gè)方法與Servlet生命周期相關(guān):
void init(ServletConfig config) throws ServletException void service(ServletRequest req, ServletResponse resp) throws ServletException, java.io.IOException void destory() java.lang.String getServletInfo() ServletConfig getServletConfig()
生命周期:
Web容器加載Servlet并將其實(shí)例化后,Servlet生命周期開始,容器運(yùn)行其init()方法進(jìn)行Servlet的初始化;
請(qǐng)求到達(dá)時(shí)調(diào)用Servlet的service()方法,service()方法會(huì)根據(jù)需要調(diào)用與請(qǐng)求對(duì)應(yīng)的doGet或doPost等方法;
當(dāng)服務(wù)器關(guān)閉或項(xiàng)目被卸載時(shí)服務(wù)器會(huì)將Servlet實(shí)例銷毀,此時(shí)會(huì)調(diào)用Servlet的destroy()方法。
init方法和destory方法只會(huì)執(zhí)行一次,service方法客戶端每次請(qǐng)求Servlet都會(huì)執(zhí)行。Servlet中有時(shí)會(huì)用到一些需要初始化與銷毀的資源,因此可以把初始化資源的代碼放入init方法中,銷毀資源的代碼放入destroy方法中,這樣就不需要每次處理客戶端的請(qǐng)求都要初始化與銷毀資源。
如果客戶端禁止 cookie 能實(shí)現(xiàn) session 還能用嗎?
Cookie 與 Session,一般認(rèn)為是兩個(gè)獨(dú)立的東西,Session采用的是在服務(wù)器端保持狀態(tài)的方案,而Cookie采用的是在客戶端保持狀態(tài)的方案。
但為什么禁用Cookie就不能得到Session呢?因?yàn)镾ession是用Session ID來(lái)確定當(dāng)前對(duì)話所對(duì)應(yīng)的服務(wù)器Session,而Session ID是通過(guò)Cookie來(lái)傳遞的,禁用Cookie相當(dāng)于失去了Session ID,也就得不到Session了。
假定用戶關(guān)閉Cookie的情況下使用Session,其實(shí)現(xiàn)途徑有以下幾種:
手動(dòng)通過(guò)URL傳值、隱藏表單傳遞Session ID。 用文件、數(shù)據(jù)庫(kù)等形式保存Session ID,在跨頁(yè)過(guò)程中手動(dòng)調(diào)用。
原文鏈接:https://thinkwon.blog.csdn.net/article/details/104903925
4.中間件等
更多信息請(qǐng)關(guān)注公眾號(hào):「軟件老王」,關(guān)注不迷路,軟件老王和他的IT朋友們,分享一些他們的技術(shù)見解和生活故事。
