一、首先講一下TCP的由來(lái)
最開始,人們考慮到將網(wǎng)絡(luò)信息的呼喚與回應(yīng)進(jìn)行規(guī)范,達(dá)成一種公認(rèn)的協(xié)議,就好像沒(méi)有交通規(guī)則的路口設(shè)定交通規(guī)則。
人們?cè)O(shè)計(jì)出完美的OSI協(xié)議,這個(gè)協(xié)議包含七個(gè)層次由下到上分別是:
物理層,數(shù)據(jù)鏈路層,網(wǎng)絡(luò)層,傳輸層,會(huì)話層,表示層,應(yīng)用層。
大家都覺(jué)得很完美但是現(xiàn)實(shí)總是會(huì)打破理想,十分現(xiàn)實(shí)。
人們發(fā)現(xiàn)在使用過(guò)程中,沒(méi)有必要這么繁瑣,很多層次也分的不必太清晰可以合并,于是在實(shí)踐過(guò)程中,人們逐漸演變出更實(shí)用的TCP/IP協(xié)議。
二、三次握手連接,四次揮手?jǐn)嚅_
畫圖解釋吧更形象
三、總結(jié)
3次握手的過(guò)程是雙方都在準(zhǔn)備資源,4次揮手的過(guò)程是讓之前準(zhǔn)備的資源釋放。
這個(gè)時(shí)候可能會(huì)產(chǎn)生疑問(wèn)為什么連接是三次揮手就要四次?
這是因?yàn)樘捉幼质侨p工的(同時(shí)收發(fā)數(shù)據(jù)無(wú)影響),所以關(guān)的時(shí)候要收發(fā)都關(guān)掉。
不知道有沒(méi)有同學(xué)會(huì)跟我一樣產(chǎn)生一個(gè)疑惑,為什么要客戶端先調(diào)用close而不是服務(wù)器先調(diào)用close?
我經(jīng)過(guò)查閱資料學(xué)習(xí)我們先來(lái)追溯一下收發(fā)信息原理的源頭:TCP為了保證數(shù)據(jù)的可靠性,一般接收方在收到一個(gè)數(shù)據(jù)“請(qǐng)求斷開連接”之后才會(huì)給發(fā)出方回應(yīng)一個(gè)“收到,這邊準(zhǔn)備妥當(dāng)不再接收”信息,但如果一直不回應(yīng),發(fā)送方就會(huì)一直等待回應(yīng),為了避免陷入這樣一個(gè)循環(huán),引入了超時(shí)時(shí)間機(jī)制,誰(shuí)先調(diào)用close,發(fā)完消息之后等待一定時(shí)間,如果沒(méi)有收到回應(yīng),發(fā)送方就再發(fā)送一次。但這個(gè)時(shí)候又出現(xiàn)一個(gè)問(wèn)題,如果接收方給的回應(yīng)遲了,超出了等待期限范疇,一邊已經(jīng)回應(yīng)“收到,已準(zhǔn)備妥當(dāng)不再接收”,另一邊因?yàn)榈却龝r(shí)間內(nèi)沒(méi)有等到這條消息,會(huì)繼續(xù)發(fā)送“請(qǐng)求斷開連接”-等待(對(duì)方已經(jīng)關(guān)閉接收了)-發(fā)-等待-發(fā)-等待…這就又陷入了一個(gè)循環(huán),為了解決這個(gè)問(wèn)題,我們引入了延時(shí)機(jī)制,也就是接收方接到斷開請(qǐng)求,回復(fù)“收到,這邊準(zhǔn)備妥當(dāng)不再接收”之后,讓它等待約2MSL(MSL就是一個(gè)數(shù)據(jù)包在網(wǎng)絡(luò)上傳輸?shù)臅r(shí)間),確定收不到發(fā)送方再次發(fā)來(lái)的斷開請(qǐng)求,再真正執(zhí)行關(guān)閉接收操作?,F(xiàn)實(shí)這段過(guò)程大概耗時(shí)為兩分鐘左右,在這段時(shí)間內(nèi)接收方是不被允許釋放資源的,這也就意味著這段時(shí)間內(nèi)它所占用的端口不可以被其他程序所調(diào)用(程序雖然關(guān)了但是端口仍被占用,不利于資源的最大化利用)。這個(gè)時(shí)候,我們?cè)賮?lái)想,如果是服務(wù)器先調(diào)用close,這就意味著服務(wù)器先發(fā)出斷開連接請(qǐng)求,也就意味著它要保留兩分鐘左右的資源的同時(shí)占用這個(gè)端口,但我們知道,服務(wù)端要綁定固定的端口,客戶端不用呀,所以如果是客戶端先調(diào)用close,它在等待保留資源的時(shí)候,操作系統(tǒng)再執(zhí)行其他操作,分配資源時(shí),端口是自由的,可以緊接著繼續(xù)分配,達(dá)到對(duì)資源的最大化利用,剛剛好。所以客戶端先調(diào)用close而不是服務(wù)器先調(diào)用close。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-842209.html
上碼
import socket
def service_client(new_socket):
"""為這個(gè)客戶端返回?cái)?shù)據(jù)"""
#1.接收瀏覽器發(fā)送過(guò)來(lái)的請(qǐng)求,即HTTP發(fā)送來(lái)的請(qǐng)求
#GET /HTTP/2.0
#...
request=new_socket.recv(1024)#一般來(lái)說(shuō)應(yīng)該空間是夠了
print(request)
#2.返回HTTP格式的數(shù)據(jù)給瀏覽器
#2.1準(zhǔn)備發(fā)送給瀏覽器的數(shù)據(jù)--head就是HTML那些
response="http/2.0 200 OK\r\n"#瀏覽器不能解析換行符/n,必須使用/r/n的方式
response+="\r\n"#不可或缺的換行符,代表著body即將到來(lái)
#2.2準(zhǔn)備一些--body部分內(nèi)容,準(zhǔn)備給瀏覽器送去
#response+="<h1>xixizi</h1>"
response+="xixizi"
new_socket.send(response.encode("utf-8"))
#關(guān)閉套接字
new_socket.close()
def main():
"用來(lái)完成整體的控制"
#1.創(chuàng)建套接字
tcp_server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#2.綁定
tcp_server_socket.bind(("",65534))
#3.變?yōu)楸O(jiān)聽(tīng)套接字
tcp_server_socket.listen(128)
while True:
#4.等待新客戶端的鏈接
new_socket,client_addr=tcp_server_socket.accept()
#5.為這個(gè)客戶端服務(wù)
service_client(new_socket)
#關(guān)閉監(jiān)聽(tīng)套接字
tcp_server_socket.close()
if __name__=="__main__":
main()
最近很努力在找實(shí)習(xí),把塵封已久的知識(shí)重新翻出來(lái)再溫習(xí)溫習(xí),不問(wèn)前程,但行腳下文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-842209.html
到了這里,關(guān)于TCP的三次握手和4次揮手的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!