TCP/UDP协议是什么?深入理解TCP、UDP协议及两者的区别
一、TCP协议:
位于传输(shu)层, 提供可(ke)(ke)靠(kao)的(de)字(zi)节(jie)流服(fu)务。所谓的(de)字(zi)节(jie)流服(fu)务(Byte Stream Service) 是(shi)(shi)指, 为(wei)(wei)了方便传输(shu), 将(jiang)大(da)块(kuai)数(shu)(shu)据(ju)(ju)分割成以(yi)报文段(segment) 为(wei)(wei)单位的(de)数(shu)(shu)据(ju)(ju)包进行管理。 而可(ke)(ke)靠(kao)的(de)传输(shu)服(fu)务是(shi)(shi)指, 能够把(ba)(ba)数(shu)(shu)据(ju)(ju)准确可(ke)(ke)靠(kao)地传给对方。 即TCP 协议为(wei)(wei)了更容易传送大(da)数(shu)(shu)据(ju)(ju)才把(ba)(ba)数(shu)(shu)据(ju)(ju)分割, 而且 TCP 协议能够确认(ren)数(shu)(shu)据(ju)(ju)最终(zhong)是(shi)(shi)否送达到对方。所以(yi),TCP连接相当于两(liang)根管道(dao)(一(yi)(yi)(yi)个用(yong)于服(fu)务器到客户(hu)端,一(yi)(yi)(yi)个用(yong)于客户(hu)端到服(fu)务器),管道(dao)里面数(shu)(shu)据(ju)(ju)传输(shu)是(shi)(shi)通过(guo)字(zi)节(jie)码(ma)传输(shu),传输(shu)是(shi)(shi)有(you)序的(de),每个字(zi)节(jie)都是(shi)(shi)一(yi)(yi)(yi)个一(yi)(yi)(yi)个来传输(shu)。
(1)、三次(ci)握手:握手过程中(zhong)使用了 TCP 的标(biao)志(flag) —— SYN(synchronize) 和ACK(acknowledgement) 。
第(di)一次握手:建立连接时,客户端A发送SYN包(bao)(SYN=j)到服务(wu)器B,并进入SYN_SEND状态,等待服务(wu)器B确认。
第二次(ci)握手:服务器B收到SYN包(bao),必须确认客户A的(de)SYN(ACK=j+1),同时自己也发送一个SYN包(bao)(SYN=k),即(ji)SYN+ACK包(bao),此时服务器B进入(ru)SYN_RECV状态。
第三(san)次握手(shou):客户端A收到服务(wu)(wu)器(qi)B的SYN+ACK包,向服务(wu)(wu)器(qi)B发送(song)确认包ACK(ACK=k+1),此包发送(song)完毕(bi),完成(cheng)三(san)次握手(shou)。
若在握手过程中(zhong)某个阶段莫(mo)名中(zhong)断, TCP 协议会再次以相(xiang)同的顺序发送相(xiang)同的数据(ju)包。
(2)、四次挥手:由于TCP连(lian)(lian)接是全双工的,因此每个(ge)(ge)(ge)方向(xiang)都必须(xu)单独进(jin)行(xing)(xing)关(guan)闭(bi)。这(zhei)个(ge)(ge)(ge)原则是当(dang)一(yi)方完(wan)成它的数据发(fa)送任务后就(jiu)能(neng)发(fa)送一(yi)个(ge)(ge)(ge)FIN来(lai)终止(zhi)这(zhei)个(ge)(ge)(ge)方向(xiang)的连(lian)(lian)接。收到(dao)一(yi)个(ge)(ge)(ge) FIN只(zhi)意(yi)味着这(zhei)一(yi)方向(xiang)上(shang)没有数据流动(dong),一(yi)个(ge)(ge)(ge)TCP连(lian)(lian)接在收到(dao)一(yi)个(ge)(ge)(ge)FIN后仍能(neng)发(fa)送数据。先(xian)进(jin)行(xing)(xing)关(guan)闭(bi)的一(yi)方将执行(xing)(xing)主(zhu)动(dong)关(guan)闭(bi),而(er)另一(yi)方被动(dong)关(guan)闭(bi)。
客户端A发送一个FIN,用来关闭(bi)客户A到服务器B的(de)数(shu)据(ju)传送。
服务器(qi)B收到这个FIN,它发回一个ACK,确(que)认序(xu)号(hao)为收到的序(xu)号(hao)加1。
服务器B关闭与客户端(duan)A的连接,发送一个(ge)FIN给客户端(duan)A。
客户端A发回ACK报文确认,并将(jiang)确认序号(hao)设置为收到(dao)序号(hao)加(jia)1。
三次握手(shou)和四(si)次挥手(shou):在(zai)(zai)TCP连(lian)接(jie)中,服务器端(duan)的SYN和ACK向(xiang)客户端(duan)发送(song)是(shi)一(yi)次性发送(song)的,而(er)在(zai)(zai)断开连(lian)接(jie)的过程中, B端(duan)向(xiang)A
端发(fa)送(song)(song)的ACK和FIN是分两次发(fa)送(song)(song)的。因为(wei)在B端接收(shou)到A端的FIN后(hou), B端可能还有数(shu)据要(yao)传输,所(suo)以(yi)先发(fa)送(song)(song)ACK,等B端处理完自己的事情后(hou)就可以(yi)发(fa)送(song)(song)FIN断开连接了。
(3)、深入理解TCP连接(jie):
由(you)于TCP是(shi)全双工的,因(yin)此在(zai)每一个(ge)(ge)方(fang)向(xiang)都必须单独关闭。这原则是(shi)当一方(fang)完成它的数据发送(song)任务后就能(neng)发送(song)一个(ge)(ge)FIN来终止这个(ge)(ge)方(fang)向(xiang)的连接(jie)。收(shou)到一个(ge)(ge)FIN只意味(wei)着这个(ge)(ge)方(fang)向(xiang)上没(mei)有数据流动,一个(ge)(ge)TCP连接(jie)在(zai)接(jie)收(shou)到一个(ge)(ge)FIN后仍能(neng)发送(song)数据。 首先进行关
闭(bi)(bi)的一方将执(zhi)行主动关闭(bi)(bi),而另一方执(zhi)行被动关闭(bi)(bi)。
TCP协议的连(lian)接是全双工连(lian)接,一个TCP连(lian)接存(cun)在双向的读写通道(dao)。简单来说,是“先关(guan)读,再关(guan)写” ,总(zong)共(gong)需要4个阶段。以客户(hu)机发起关(guan)闭(bi)连(lian)接为(wei)例:1.服务器读通道(dao)关(guan)闭(bi);2.客户(hu)端写通道(dao)关(guan)闭(bi);3.客户(hu)端读通道(dao)关(guan)闭(bi);4.服务器写通道(dao)关(guan)闭(bi)。
关闭行(xing)为(wei)是在(zai)发(fa)(fa)起方(fang)数据(ju)发(fa)(fa)送完毕之(zhi)后(hou),给对方(fang)发(fa)(fa)出一个FIN(finish)数据(ju)段(duan),直到接(jie)收(shou)到对方(fang)发(fa)(fa)送的(de)FIN,且对方(fang)收(shou)到了接(jie)收(shou)确(que)认的(de)ACK之(zhi)后(hou),双(shuang)方(fang)的(de)数据(ju)通信完全结束,过程中每次都需要返回确(que)认数据(ju)段(duan)ACK。
(4)、TCP使用滑动窗口机制(zhi)(zhi)来进行流(liu)量(liang)控(kong)制(zhi)(zhi)。
建立连接时,各端分(fen)配一(yi)(yi)个缓(huan)(huan)冲(chong)区用来存储接收(shou)的(de)(de)数据,并将缓(huan)(huan)冲(chong)区的(de)(de)尺(chi)寸发送给(ji)另一(yi)(yi)端。接收(shou)方发送的(de)(de)确认(ren)消息中包含了(le)自己剩余(yu)的(de)(de)缓(huan)(huan)冲(chong)区尺(chi)寸。剩余(yu)缓(huan)(huan)冲(chong)区空间的(de)(de)数量叫做窗口。其(qi)实就(jiu)是建立连接的(de)(de)双虎互相(xiang)知道彼此剩余(yu)的(de)(de)缓(huan)(huan)冲(chong)区大小。
(5)、拥塞(sai)控制
拥(yong)塞(sai)控制(zhi):防止(zhi)过(guo)多的(de)数(shu)据注入到网路(lu)(lu)中,这样(yang)可以使网络中的(de)路(lu)(lu)由器或(huo)链路(lu)(lu)不至于(yu)阻(zu)塞(sai)。拥(yong)塞(sai)控制(zhi)是一个全局(ju)性(xing)的(de)过(guo)程,和流量控制(zhi)不同,流量控制(zhi)是点对点的(de)控制(zhi)。
1、慢开始:发送(song)方维持(chi)一个叫做拥(yong)塞窗(chuang)(chuang)(chuang)口cwnd(congestion window)的(de)(de)(de)(de)状态(tai)变量。拥(yong)塞窗(chuang)(chuang)(chuang)口的(de)(de)(de)(de)大小取决于网络的(de)(de)(de)(de)拥(yong)塞程度,并且动态(tai)的(de)(de)(de)(de)变化(hua)。发送(song)方让(rang)自(zi)己的(de)(de)(de)(de)发送(song)窗(chuang)(chuang)(chuang)口等(deng)于拥(yong)塞窗(chuang)(chuang)(chuang)口,另(ling)外考虑到(dao)接(jie)收方的(de)(de)(de)(de)接(jie)收能力,发送(song)窗(chuang)(chuang)(chuang)口可能小于拥(yong)塞窗(chuang)(chuang)(chuang)口。思路就是:不要(yao)一开始就发送(song)大量的(de)(de)(de)(de)数(shu)据,先试探一下网络的(de)(de)(de)(de)拥(yong)塞程度,也就是说由小到(dao)大增加拥(yong)塞窗(chuang)(chuang)(chuang)口的(de)(de)(de)(de)大小。
为了防止cwnd增长(zhang)过大(da)引起网络拥塞,还需要设置一个慢(man)开始门限ssthresh状(zhuang)态变量。 ssthresh的(de)方法如下(xia):
当(dang)cwnd < ssthresh时(shi),开(kai)始(shi)使用(yong)慢(man)开(kai)始(shi)算法;当(dang)cwnd > ssthresh, 改用(yong)拥塞避免(mian)算法;当(dang)cwnd = ssthresh时(shi),慢(man)开(kai)始(shi)与拥塞算法任意。
2.拥塞避免(mian):
拥(yong)塞(sai)(sai)避免算(suan)法(fa)(fa)让拥(yong)塞(sai)(sai)窗(chuang)口缓慢(man)增长(zhang),即(ji)每经(jing)过一个(ge)往返时(shi)间RTT就(jiu)把发送方(fang)的(de)拥(yong)塞(sai)(sai)窗(chuang)口cwnd加(jia)1,而不是(shi)加(jia)倍(bei),这样拥(yong)塞(sai)(sai)窗(chuang)口按照线性(xing)规律缓慢(man)增长(zhang)。无论是(shi)在慢(man)开(kai)始阶段(duan)还是(shi)在拥(yong)塞(sai)(sai)避免阶段(duan),只要发送方(fang)判(pan)断网络出现拥(yong)塞(sai)(sai)(其(qi)根据就(jiu)是(shi)没有收到确认,虽然没有收到确认可能是(shi)其(qi)他(ta)原(yuan)因的(de)分组丢失(shi),但是(shi)因为(wei)⽆法(fa)(fa)判(pan)定,所(suo)以都当作拥(yong)塞(sai)(sai)处理(li)),就(jiu)把慢(man)开(kai)始门限设(she)置(zhi)为(wei)出现拥(yong)塞(sai)(sai)时(shi)的(de)发送窗(chuang)口的(de)一半,然后(hou)把拥(yong)塞(sai)(sai)窗(chuang)口设(she)置(zhi)为(wei)1,执(zhi)行慢(man)开(kai)始算(suan)法(fa)(fa):
此外,还有(you)快速(su)重传和快速(su)恢复,停止-等待协议(yi),回退N帧协议(yi),选择(ze)重传协议(yi)等。
二(er)、UDP协议:
无连(lian)接(jie)协议(yi),也(ye)称透明协议(yi),也(ye)位(wei)于传输层。
两(liang)者区别:
1) TCP提供面向(xiang)连(lian)(lian)接(jie)的传(chuan)(chuan)输,通信前要(yao)先建立(li)连(lian)(lian)接(jie)(三次握手机制); UDP提供无连(lian)(lian)接(jie)的传(chuan)(chuan)输,通信前不需(xu)要(yao)建立(li)连(lian)(lian)接(jie)。
2) TCP提供(gong)可靠(kao)的传(chuan)输(shu)(有序(xu),无差错,不(bu)丢失,不(bu)重复); UDP提供(gong)不(bu)可靠(kao)的传(chuan)输(shu)。
3) TCP面(mian)向字节流的(de)传输(shu),因此它能(neng)将信(xin)息分割成组(zu)(zu),并在(zai)接收端(duan)将其重组(zu)(zu); UDP是面(mian)向数据报的(de)传输(shu),没有(you)分组(zu)(zu)开销。
4) TCP提(ti)(ti)供拥(yong)塞控(kong)制(zhi)和(he)流量(liang)控(kong)制(zhi)机制(zhi); UDP不提(ti)(ti)供拥(yong)塞控(kong)制(zhi)和(he)流量(liang)控(kong)制(zhi)机制(zhi)。
三、长(zhang)连接和(he)短连接
HTTP的长连接(jie)和(he)(he)短连接(jie)本质上是TCP长连接(jie)和(he)(he)短连接(jie)。HTTP属于应用(yong)层(ceng)协(xie)议(yi),在传(chuan)输层(ceng)使用(yong)TCP协(xie)议(yi),在网络(luo)层(ceng)使用(yong)IP协(xie)议(yi)。 IP协(xie)议(yi)主要解决(jue)网络(luo)路由和(he)(he)寻址问题,TCP协(xie)议(yi)主要解决(jue)如何在IP层(ceng)之上可靠地传(chuan)递数据包(bao),使得(de)网络(luo)上接(jie)收端收到发送(song)(song)端所发出(chu)的所有包(bao),并且顺序(xu)与发送(song)(song)顺序(xu)一致。TCP协(xie)议(yi)是可靠的、面向连接(jie)的。
在(zai)HTTP/1.0中默认使用(yong)短连(lian)接(jie)。也就(jiu)是说,客户端(duan)和服务器每进行一(yi)次HTTP操(cao)作,就(jiu)建(jian)立一(yi)次连(lian)接(jie),任(ren)务结束(shu)就(jiu)中断连(lian)接(jie)。当客户端(duan)浏(liu)(liu)览器访(fang)问的某(mou)个HTML或其(qi)他(ta)类型的Web页中包含有其(qi)他(ta)的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一(yi)个Web资源,浏(liu)(liu)览器就(jiu)会(hui)重新建(jian)立一(yi)个HTTP会(hui)话。
而从HTTP/1.1起,默(mo)认使用(yong)长连(lian)接(jie),用(yong)以保持连(lian)接(jie)特(te)性(xing)。使用(yong)长连(lian)接(jie)的(de)HTTP协议,会在响应头加(jia)入这行代(dai)码(ma):
Connection:keep-alive
在使用(yong)长(zhang)连(lian)(lian)接(jie)的(de)情况(kuang)下,当一个(ge)网页(ye)打开完成后,客(ke)户端(duan)和服务(wu)器(qi)之(zhi)间(jian)(jian)用(yong)于传输HTTP数据的(de)TCP连(lian)(lian)接(jie)不(bu)会关闭,客(ke)户端(duan)再次访问这个(ge)服务(wu)器(qi)时,会继续使用(yong)这一条已经建立的(de)连(lian)(lian)接(jie)。Keep-Alive不(bu)会永(yong)久保(bao)持(chi)连(lian)(lian)接(jie),它有一个(ge)保(bao)持(chi)时间(jian)(jian),可以在不(bu)同的(de)服务(wu)器(qi)软件(如Apache)中设定这个(ge)时间(jian)(jian)。实现长(zhang)连(lian)(lian)接(jie)需(xu)要客(ke)户端(duan)和服务(wu)端(duan)都支持(chi)长(zhang)连(lian)(lian)接(jie)。
HTTP协议的长(zhang)连(lian)接(jie)和(he)短(duan)连(lian)接(jie),实质上是TCP协议的长(zhang)连(lian)接(jie)和(he)短(duan)连(lian)接(jie)。