一文搞懂什么是TCP/IP协议
什么是TCP/IP协议?
计算机(ji)与(yu)网络(luo)设(she)备之间(jian)如果(guo)要相互(hu)通(tong)(tong)(tong)信,双方(fang)(fang)就必须基于相同(tong)(tong)的方(fang)(fang)法.比如如何探测到(dao)通(tong)(tong)(tong)信目标.由哪(na)一(yi)边先发起通(tong)(tong)(tong)信,使用哪(na)种(zhong)(zhong)语言进行通(tong)(tong)(tong)信,怎样结束通(tong)(tong)(tong)信等规则(ze)都需(xu)要事(shi)先确定.不同(tong)(tong)的硬件,操作(zuo)系统(tong)之间(jian)的通(tong)(tong)(tong)信,所有(you)这一(yi)切(qie)都需(xu)要一(yi)种(zhong)(zhong)规则(ze).而我们就将这种(zhong)(zhong)规则(ze)称为协议 (protocol).
也就是说,TCP/IP 是互联网相关各类协议族的总称。
TCP/IP 的分层管理
TCP/IP协议(yi)(yi)里最重(zhong)要的(de)一点就是(shi)分(fen)层(ceng)(ceng)。TCP/IP协议(yi)(yi)族按层(ceng)(ceng)次分(fen)别为 应用层(ceng)(ceng),传(chuan)输(shu)层(ceng)(ceng),网络层(ceng)(ceng),数据链路(lu)层(ceng)(ceng),物理层(ceng)(ceng)。当然也有按不同的(de)模(mo)型(xing)分(fen)为4层(ceng)(ceng)或者7层(ceng)(ceng)的(de)。
为什么要分层呢?
把(ba) TCP/IP 协议(yi)分层之后(hou),如果(guo)后(hou)期某(mou)个地(di)方设(she)(she)计修(xiu)改(gai),那(nei)么就(jiu)无需全部替换(huan)(huan),只需要(yao)将变(bian)动(dong)的层替换(huan)(huan)。而(er)(er)且从设(she)(she)计上来说,也变(bian)得简单了。处于应(ying)用层上的应(ying)用可以只考(kao)虑分派给自己的任务(wu),而(er)(er)不需要(yao)弄清对方在地(di)球(qiu)上哪个地(di)方,怎样(yang)传输(shu),如果(guo)确(que)保到(dao)达率(lv)等问题。
如(ru)上(shang)图所(suo)示,我(wo)们(men)将TCP/IP分(fen)为5层,越靠(kao)下(xia)越接近硬件(jian)。我(wo)们(men)由(you)下(xia)到(dao)上(shang)来了解一下(xia)这些分(fen)层。
物理层
该(gai)层负责 比特流在节点之间的(de)传(chuan)输(shu),即(ji)负责物(wu)(wu)理(li)传(chuan)输(shu),这一(yi)层的(de)协议既与(yu)链路有关,也与(yu)传(chuan)输(shu)的(de)介质有关。通俗来说(shuo)就是把计算机连接起(qi)来的(de)物(wu)(wu)理(li)手段。
数据链路层
控制(zhi)(zhi)网(wang)(wang)络层(ceng)与物(wu)理(li)层(ceng)之间的(de)通(tong)(tong)信,主要功能是(shi)保证物(wu)理(li)线路上(shang)进行(xing)可靠的(de)数据(ju)传(chuan)(chuan)递(di)。为了(le)(le)保证传(chuan)(chuan)输(shu),从网(wang)(wang)络层(ceng)接收到的(de)数据(ju)被分割(ge)成特(te)定的(de)可被物(wu)理(li)层(ceng)传(chuan)(chuan)输(shu)的(de)帧(zhen)(zhen)。帧(zhen)(zhen)是(shi)用来移(yi)动数据(ju)结构的(de)结构包,他不仅(jin)包含(han)原(yuan)始数据(ju),还包含(han)发(fa)送(song)方(fang)和(he)接收方(fang)的(de)物(wu)理(li)地址以及纠(jiu)错和(he)控制(zhi)(zhi)信息。其中的(de)地址确(que)定了(le)(le)帧(zhen)(zhen)将发(fa)送(song)到何处,而纠(jiu)错和(he)控制(zhi)(zhi)信息则确(que)保帧(zhen)(zhen)无差(cha)错到达。如果在传(chuan)(chuan)达数据(ju)时,接收点检测(ce)到所传(chuan)(chuan)数据(ju)中有差(cha)错,就要通(tong)(tong)知发(fa)送(song)方(fang)重发(fa)这一帧(zhen)(zhen)。
网络层
决(jue)定如何将数据从(cong)(cong)发送(song)(song)方(fang)路由到(dao)接收方(fang)。网络(luo)(luo)层通(tong)过综合考(kao)虑发送(song)(song)优先权,网络(luo)(luo)拥塞程度,服(fu)务(wu)质量以及(ji)可选路由的(de)花费等来决(jue)定从(cong)(cong)网络(luo)(luo)中的(de)A节点(dian)到(dao)B节点(dian)的(de)最佳途径。即建立主机到(dao)主机的(de)通(tong)信。
传输层
该层为两(liang)台(tai)主机上的(de)应(ying)用程序提供端(duan)到(dao)端(duan)的(de)通信。传(chuan)输(shu)层有两(liang)个(ge)传(chuan)输(shu)协议:TCP(传(chuan)输(shu)控制协议)和 UDP(用户数(shu)据报(bao)协议)。其中,TCP是一(yi)个(ge)可靠(kao)的(de)面向连(lian)接的(de)协议,udp是不可靠(kao)的(de)或者说(shuo)无连(lian)接的(de)协议
应用层
应(ying)用程序(xu)收到传输层的数(shu)据(ju)后,接下来就要进行解(jie)(jie)读。解(jie)(jie)读必须事(shi)先规定好(hao)格式,而应(ying)用层就是规定应(ying)用程序(xu)的数(shu)据(ju)格式。主(zhu)要的协议有(you):HTTP.FTP,Telent等。
TCP与UDP
TCP/UDP 都是传(chuan)输层协议,但是两者具有不(bu)同的(de)(de)特效,同时也具有不(bu)同的(de)(de)应用(yong)场景。
面向报文
面向报(bao)文(wen)的(de)传(chuan)输方式是应(ying)用(yong)(yong)层(ceng)交给UDP多长(zhang)的(de)报(bao)文(wen),UDP发送多长(zhang)的(de)报(bao)文(wen),即一(yi)(yi)次发送一(yi)(yi)个报(bao)文(wen)。因此,应(ying)用(yong)(yong)程序必(bi)须选(xuan)择合适大小(xiao)的(de)报(bao)文(wen)。
面向字节流
虽然应(ying)(ying)用程序和TCP的交互是一(yi)(yi)(yi)次(ci)一(yi)(yi)(yi)个数据(ju)块(大小不(bu)等),但(dan)TCP把(ba)应(ying)(ying)用程序看(kan)成是一(yi)(yi)(yi)连串(chuan)的无(wu)结(jie)构的字节流。TCP有一(yi)(yi)(yi)个缓冲(chong),当应(ying)(ying)该程序传送的数据(ju)块太长(zhang),TCP就可以(yi)把(ba)它划分短一(yi)(yi)(yi)些再传送。
TCP的三次握手与四次挥手
具体过程如下:
第一次握手:建立连(lian)(lian)接(jie)。客户(hu)端(duan)发送连(lian)(lian)接(jie)请(qing)求(qiu)报文段(duan),并将(jiang)syn(标记(ji)位(wei))设置为1,Squence Number(数据包序号)(seq)为x,接(jie)下来等待(dai)服(fu)务端(duan)确认,客户(hu)端(duan)进入SYN_SENT状态(请(qing)求(qiu)连(lian)(lian)接(jie));
第二次握手(shou):服务(wu)(wu)端(duan)收到客户端(duan)的 SYN 报文段(duan)(duan),对 SYN 报文段(duan)(duan)进行(xing)确认(ren),设置(zhi) ack(确认(ren)号)为 x+1(即seq+1 ; 同(tong)时(shi)自己还(hai)要发(fa)送(song) SYN 请(qing)求信(xin)息,将 SYN 设置(zhi)为1, seq为 y。服务(wu)(wu)端(duan)将上(shang)述所有信(xin)息放到 SYN+ACK 报文段(duan)(duan)中(zhong),一并发(fa)送(song)给客户端(duan),此时(shi)服务(wu)(wu)器进入 SYN_RECV状态。
SYN_RECV是指,服务端(duan)被(bei)动打开后,接(jie)收(shou)到了(le)客(ke)户端(duan)的SYN并且发送了(le)ACK时(shi)的状态。再进一步接(jie)收(shou)到客(ke)户端(duan)的ACK就进入ESTABLISHED状态。
第(di)三次(ci)握手(shou):客户端收到服务(wu)(wu)端的 SYN+ACK(确认符) 报(bao)文段(duan);然后(hou)(hou)将 ACK 设置(zhi)为 y+1,向(xiang)服务(wu)(wu)端发(fa)送ACK报(bao)文段(duan),这个报(bao)文段(duan)发(fa)送完毕后(hou)(hou),客户端和(he)服务(wu)(wu)端都进入(ru)ESTABLISHED(连接成功)状态,完成TCP 的三次(ci)握手(shou)。
上面(mian)的解(jie)释可能有点不好(hao)理解(jie),用(yong)《图解(jie)HTTP》中的一副插(cha)图 帮(bang)助大(da)家。
当客户端和服务端通过三次握手建立了 TCP 连接以后,当数据传送完毕,断开连接就需要进行TCP的四次挥手。其四次挥手如下所示:
第一次挥手
客(ke)户端设置seq和 ACK ,向服(fu)务(wu)器(qi)发送一个(ge) FIN(终结)报(bao)文(wen)段(duan)。此(ci)时(shi),客(ke)户端进入 FIN_WAIT_1 状(zhuang)态,表示客(ke)户端没(mei)有数据要发送给服(fu)务(wu)端了(le)。
第二次挥手
服务端(duan)收到(dao)了客户端(duan)发(fa)送的 FIN 报(bao)文(wen)(wen)段(duan),向(xiang)客户端(duan)回了一个 ACK 报(bao)文(wen)(wen)段(duan)。
第三次挥手
服(fu)务端向客户端发送FIN 报文段,请(qing)求关(guan)闭连(lian)接,同时服(fu)务端进入 LAST_ACK 状态。
第四次挥(hui)手(shou)
客(ke)户(hu)端(duan)收(shou)到服务(wu)端(duan)发送的 FIN 报文段后,向服务(wu)端(duan)发送 ACK 报文段,然后客(ke)户(hu)端(duan)进入 TIME_WAIT 状态(tai)。服务(wu)端(duan)收(shou)到客(ke)户(hu)端(duan)的 ACK 报文段以后,就(jiu)关闭(bi)连接。此时,客(ke)户(hu)端(duan)等待 2MSL(指(zhi)一个片(pian)段在网络中最大的存(cun)活时间)后依然没有收(shou)到回复,则说明服务(wu)端(duan)已经(jing)正常(chang)关闭(bi),这样(yang)客(ke)户(hu)端(duan)就(jiu)可(ke)以关闭(bi)连接了。
最后再看一(yi)下完整(zheng)的(de)过程:
如果有大量的连接,每次在连接,关闭都要经历三次握手,四次挥手,这显然会造成性能低下。因此。Http 有一种叫做 长连接(keepalive connections) 的机制。它可以在传输数据后仍保持连接,当客户端需要再次获取数据时,直接使用刚刚空闲下来的连接而无需再次握手。
一些问题汇总:
1. 为什么要三次握手?
为(wei)了(le)防止已(yi)失效的连接请求报文突然又传送到(dao)了(le)服务端,因(yin)为(wei)产生(sheng)错(cuo)误。
具体解释: “已失效的连接请求(qiu)报文段”产生情况:
client 发(fa)(fa)出的(de)(de)(de)第一(yi)个(ge)连(lian)(lian)接(jie)请(qing)求(qiu)报文段(duan)并(bing)没有丢(diu)失(shi),而是(shi)在某个(ge)网(wang)络(luo)节点长时(shi)间(jian)滞留(liu),因(yin)此(ci)导致延误(wu)到连(lian)(lian)接(jie)释放(fang)以后的(de)(de)(de)某个(ge)时(shi)间(jian)才到达 service。如(ru)果(guo)没有三次握(wo)手,那么此(ci)时(shi)server收(shou)到此(ci)失(shi)效(xiao)的(de)(de)(de)连(lian)(lian)接(jie)请(qing)求(qiu)报文段(duan),就误(wu)认(ren)为是(shi) client再次发(fa)(fa)出的(de)(de)(de)一(yi)个(ge)新(xin)的(de)(de)(de)连(lian)(lian)接(jie)请(qing)求(qiu),于是(shi)向 client 发(fa)(fa)出确认(ren)报文段(duan),同意建立连(lian)(lian)接(jie),而此(ci)时(shi) client 并(bing)没有发(fa)(fa)出建立连(lian)(lian)接(jie)的(de)(de)(de)情况(kuang),因(yin)此(ci)并(bing)不(bu)会(hui)(hui)理(li)会(hui)(hui)服务端的(de)(de)(de)响(xiang)应,而service将会(hui)(hui)一(yi)直等待client发(fa)(fa)送数据,因(yin)此(ci)就会(hui)(hui)导致这条连(lian)(lian)接(jie)线路(lu)白白浪费。
如(ru)果此时变成两次挥手行(xing)不行(xing)?
这个时(shi)候需要明(ming)白(bai)全(quan)双工(gong)与半双工(gong),再进(jin)行回答。比如:
第一次握手: A给B打电话说,你可以听(ting)到我(wo)说话吗?
第二(er)次(ci)握手: B收到(dao)了A的信息,然(ran)后对A说: 我(wo)可(ke)以听得到(dao)你说话啊,你能(neng)听得到(dao)我(wo)说话吗(ma)?
第三次握手: A收到(dao)了B的信息(xi),然后说可以的,我(wo)要给你发信息(xi)啦!
在三次握(wo)手(shou)之后,A和B都能(neng)确(que)定这么(me)一件事: 我说的(de)话(hua),你能(neng)听到; 你说的(de)话(hua),我也能(neng)听到。 这样,就可以开始正常通信了(le),如果(guo)是两(liang)次,那将无法确(que)定。
2. 为什么要四次挥手?
TCP 协议是一种面向连接,可靠,基于字节流(liu)的(de)传(chuan)输(shu)层(ceng)通(tong)信(xin)协议。TCP 是全(quan)双工模式(同一时(shi)(shi)(shi)刻可以同时(shi)(shi)(shi)发(fa)(fa)(fa)送(song)和接收(shou)),这就(jiu)意味着,当主机(ji)(ji)1发(fa)(fa)(fa)出 FIN 报(bao)文段(duan)时(shi)(shi)(shi),只是表示(shi)主机(ji)(ji)1已结没(mei)有(you)数(shu)据(ju)(ju)要(yao)发(fa)(fa)(fa)送(song)了(le)(le),主机(ji)(ji)1告诉主机(ji)(ji)2,它的(de)数(shu)据(ju)(ju)已经全(quan)部(bu)发(fa)(fa)(fa)送(song)完(wan)毕(bi);但(dan)是,这个时(shi)(shi)(shi)候主机(ji)(ji)1还(hai)是可以接受来自主机(ji)(ji)2的(de)数(shu)据(ju)(ju);当主机(ji)(ji)2返(fan)回(hui) ACK报(bao)文段(duan)时(shi)(shi)(shi),这个时(shi)(shi)(shi)候就(jiu)表示(shi)主机(ji)(ji)2也没(mei)有(you)数(shu)据(ju)(ju)要(yao)发(fa)(fa)(fa)送(song)了(le)(le),就(jiu)会(hui)告诉主机(ji)(ji)1,我也没(mei)有(you)数(shu)据(ju)(ju)要(yao)发(fa)(fa)(fa)送(song)了(le)(le),之后彼此就(jiu)会(hui)中断这次(ci)TCP连接。
3.为什么要等待 2MSL
MSL:报(bao)文(wen)段(duan)最(zui)大生存(cun)时间,它是任何报(bao)文(wen)段(duan)被(bei)丢(diu)弃前在网络内的最(zui)长时间
原因如下(xia):
保证TCP协议的全(quan)双工连(lian)接能够可靠关闭
保(bao)证这次连接(jie)的重(zhong)复数(shu)据从网络(luo)中消息(xi)
第一点: 如果主(zhu)机(ji)1直接(jie)(jie) 关闭,由(you)于IP协议的(de)不可靠性或者其他网络原因(yin),导致主(zhu)机(ji)2没有(you)收(shou)到(dao)主(zhu)机(ji)1最后(hou)回复的(de) ACK。那么主(zhu)机(ji)2就(jiu)会在超时(shi)(shi)(shi)之(zhi)后(hou)继续发送 FIN,此时(shi)(shi)(shi)由(you)于主(zhu)机(ji)1已经关闭,就(jiu)找不到(dao)与重发的(de) FIN 对应的(de)连接(jie)(jie)。所(suo)以(yi),主(zhu)机(ji)1 不是直接(jie)(jie)进入 关闭,而是TIME_WAIT 状态(tai)。当再次收(shou)到(dao) FIN 的(de)时(shi)(shi)(shi)候,能够保证对方(fang)收(shou)到(dao) ACK ,最后(hou)正(zheng)确关闭连接(jie)(jie)。
第二点:如果主(zhu)机(ji)1直接(jie)(jie)(jie) 关闭,然(ran)后又再(zai)向主(zhu)机(ji) 2 发起一个(ge)新(xin)连(lian)(lian)(lian)接(jie)(jie)(jie),我们(men)不(bu)能保(bao)(bao)证这(zhei)个(ge)新(xin)连(lian)(lian)(lian)接(jie)(jie)(jie)与刚才关闭的(de)(de)(de)(de)(de)连(lian)(lian)(lian)接(jie)(jie)(jie)端(duan)口(kou)(kou)是(shi)不(bu)同(tong)的(de)(de)(de)(de)(de)。也(ye)就(jiu)(jiu)是(shi)说有可能新(xin)连(lian)(lian)(lian)接(jie)(jie)(jie)和(he)(he)老(lao)(lao)连(lian)(lian)(lian)接(jie)(jie)(jie)的(de)(de)(de)(de)(de)端(duan)口(kou)(kou)号是(shi)相同(tong)的(de)(de)(de)(de)(de)。一般来说不(bu)会(hui)发生什么(me)问(wen)题,但(dan)还(hai)是(shi)有特殊情况出现;假设(she)新(xin)连(lian)(lian)(lian)接(jie)(jie)(jie)和(he)(he)已(yi)经关闭的(de)(de)(de)(de)(de)老(lao)(lao)连(lian)(lian)(lian)接(jie)(jie)(jie)端(duan)口(kou)(kou)号是(shi)一样的(de)(de)(de)(de)(de),如果前一次连(lian)(lian)(lian)接(jie)(jie)(jie)的(de)(de)(de)(de)(de)某(mou)些数(shu)据仍然(ran)滞留在(zai)(zai)网(wang)络中( Lost Duplicate ),那些延迟数(shu)据在(zai)(zai)建立新(xin)连(lian)(lian)(lian)接(jie)(jie)(jie)之后才到(dao)达主(zhu)机(ji)2,由于(yu)新(xin)连(lian)(lian)(lian)接(jie)(jie)(jie)和(he)(he)老(lao)(lao)连(lian)(lian)(lian)接(jie)(jie)(jie)的(de)(de)(de)(de)(de)端(duan)口(kou)(kou)号是(shi)一样的(de)(de)(de)(de)(de),TCP 协议就(jiu)(jiu)认为(wei)哪个(ge)延迟的(de)(de)(de)(de)(de)数(shu)据时属(shu)于(yu)新(xin)连(lian)(lian)(lian)接(jie)(jie)(jie)的(de)(de)(de)(de)(de),这(zhei)样就(jiu)(jiu)和(he)(he)真正的(de)(de)(de)(de)(de)新(xin)连(lian)(lian)(lian)接(jie)(jie)(jie)的(de)(de)(de)(de)(de)数(shu)据包发生混淆了。所以TCP连(lian)(lian)(lian)接(jie)(jie)(jie)要(yao)在(zai)(zai) TIME_WAIT 状态等待(dai)两倍 MSL ,保(bao)(bao)证本次连(lian)(lian)(lian)接(jie)(jie)(jie)的(de)(de)(de)(de)(de)所有数(shu)据都从网(wang)络中消失。