您的位置:首页 > 理论基础 > 计算机网络

HTTP/TCP 相关 三次握手 四次挥手 窗口滑动 拥塞控制

2018-03-05 08:38 323 查看
“传输控制协议”(TCP),亦称作“基于数据流的套接字”。可靠,但具有非常高的开销。    我们认为TCP和UDP端口是相互独立的。也就是说,可以在端口8080同时运行一个TCP和UDP服务程序,两者之间不会产生冲突。
   
转:http://zhaochj.blog.51cto.com/368705/1317226

TCP((Transmission Control Protocol)

        传输控制协议,是一个面向连接的协议。在运用此协议进行数据传输前都会进行连接的建立工作(三次握手);当数据传输完毕,连接的双方都会通知对方要释放此连接(四次挥手)。认识TCP标志位tcp标志位有6种标示:SYN(synchronous建立联机)ACK(acknowledgement 确认)PSH(push传送)FIN(finish结束)RST(reset重置)URG(urgent紧急)
图解TCP与UDP的三次握手与四次挥手过程



三次握手过程:

第一次握手:host1发送一个TCP标志位SYN=1、ACK=0的数据包给host2,并随机会产生一个Sequence number=3233.当host2接收到这个数据后,host2由SYN=1可知客户端是想要建立连接;
第二次握手:host2要对客户端的联机请求进行确认,向host1发送应答号ACK=1、SYN=1、确认号Acknowledge number=3234,此值是host1的序列号加1,还会产生一个随机的序列号Sequence number=36457,这样就告诉host1可以进行连接;
第三次握手:host1收到数据后检查Acknowledge number是否是3233+1的值,以及ACK的值是否为1,若为1,host1会发送ACK=1、确认号码Acknowledge number=36457,告诉host2,你的请求连接被确认,连接可以建立。

四次挥手过程:

第一次挥手:当传输的数据到达尾部时,host1向host2发送FIN=1标志位;可理解成,host1向host2说,我这边的数据传送完成了,我准备断开了连接;
第二次挥手:因TCP的连接是全双工的双向连接,关闭也是要从两边关闭;当host2收到host1发来的FIN=1的标志位后,host2不会立刻向host1发送FIND=1的请求关闭信息,而是先向host1发送一个ACK=1的应答信息,表示:你请求关闭的请求我已经收到,但我可能还有数据没有完成传送,你再等下,等我数据传输完成了我就告诉你;
第三次挥手:host2数据传输完成,向host1发送FIN=1,host1收到请求关闭连接的请求后,host1就明白host2的数据已传输完成,现在可以断开连接了,
第四次挥手:

host1收到FIND=1后,host1还是怕由于网络不稳定的原因,怕host2不知道他要断开连接,于是向host2发送ACK=1确认信息进行确认,把自己设置成TIME_WAIT状态并启动定时器,如果host2没有收到ACK,host2端TCP的定时器到达后,会要求host1重新发送ACK,当host2收到ACK后,host2就断开连接;当host1等待2MLS(2倍报文最大生存时间)后,没有收到host2的重传请求后,他就知道host2已收到了ACK,所以host1此时才关闭自己的连接。这一点我觉得设计得非常巧妙!

整个过程host1端所经历的状态如下:



host2所经历的过程如下:


总结:以前对TCP的三次握手与四次挥手没有进行深入的理解,只是一知半解,现在参照网上的一些资料写了此博文,对此知识点有了深刻认识。在TCP连接的建立与释放的过程中,host1与host2并没有严格的客户端与服务器之分,谁先发起请求,那就是客户端。
【注意】 在TIME_WAIT状态中,如果TCP client端最后一次发送的ACK丢失了,它将重新发送。TIME_WAIT状态中所需要的时间是依赖于实现方法的。典型的值为30秒、1分钟和2分钟。等待之后连接正式关闭,并且所有的资源(包括端口号)都被释放。【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文

转自:wireshark抓包图解-tcp三次握手四次挥手详解 http://www.seanyxie.com/wireshark%e6%8a%93%e5%8c%85%e5%9b%be%e8%a7%a3-tcp%e4%b8%89%e6%ac%a1%e6%8f%a1%e6%89%8b%e5%9b%9b%e6%ac%a1%e6%8c%a5%e6%89%8b%e8%af%a6%e8%a7%a3/

一. TCP/IP协议族

      TCP/IP是一个协议族,通常分不同层次进行开发,每个层次负责不同的通信功能。包含以下四个层次:

1. 链路层,也称作数据链路层或者网络接口层,通常包括操作系统中的设备驱动程序和计算机中对应的网络接口卡。它们一起处理与电缆(或其他任何传输媒介)的物理接口细节。2. 网络层,也称作互联网层,处理分组在网络中的活动,例如分组的选路。网络层协议包括IP协议(网际协议)、ICMP协议(Internet互联网控制报文协议),以及IGMP协议(Internet组管理协议)。3. 运输层主要为两台主机上的应用程序提供端到端的通信。在TCP/IP协议族中,有两个互不相同的传输协议:TCP(传输控制协议)和UDP(用户数据报协议)。TCP为两台主机提供高可靠性的数据通信。他所作的工作包括把应用程序交给它的数据分成合适的小块交给下面的网络层,确认接收到的分组,设置发送最后确认分组的超时时钟等。由于运输层提供了高可靠性的端到端通信,因此应用层可以忽略所有这些细节。而另一方面,UDP则为应用层提供一种非常简单的服务。它只是把称作数据报的分组从一台主机发送到另一台主机,但并不保证该数据报能到达另一端。任何必须的可靠性必须由应用层来提供。4. 应用层负责处理特定的应用程序细节。包括Telnet(远程登录)、FTP(文件传输协议)、SMTP(简单邮件传送协议)以及SNMP(简单网络管理协议)等。wireshark抓到的包与对应的协议层如下图所示:

1. Frame:   物理层的数据帧概况2. Ethernet II: 数据链路层以太网帧头部信息3. Internet Protocol Version 4: 互联网层IP包头部信息4. Transmission Control Protocol:  传输层的数据段头部信息,此处是TCP5. Hypertext Transfer Protocol:  应用层的信息,此处是HTTP协议

二. TCP协议

      TCP是一种面向连接(连接导向)的、可靠的基于字节流的传输层通信协议。TCP将用户数据打包成报文段,它发送后启动一个定时器,另一端收到的数据进行确认、对失序的数据重新排序、丢弃重复数据。      TCP的特点有:1. TCP是面向连接的运输层协议2. 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的3. TCP提供可靠交付的服务4. TCP提供全双工通信。数据在两个方向上独立的进行传输。因此,连接的每一端必须保持每个方向上的传输数据序号。5. 面向字节流。面向字节流的含义:虽然应用程序和TCP交互是一次一个数据块,但TCP把应用程序交下来的数据仅仅是一连串的无结构的字节流      TCP报文首部,如下图所示:

1. 源端口号:数据发起者的端口号,16bit2. 目的端口号:数据接收者的端口号,16bit3. 序号:32bit的序列号,由发送方使用4. 确认序号:32bit的确认号,是接收数据方期望收到发送方的下一个报文段的序号,因此确认序号应当是上次已成功收到数据字节序号加1。5. 首部长度:首部中32bit字的数目,可表示15*32bit=60字节的首部。一般首部长度为20字节。6. 保留:6bit, 均为07. 紧急URG:当URG=1时,表示报文段中有紧急数据,应尽快传送。8. 确认比特ACK:ACK = 1时代表这是一个确认的TCP包,取值0则不是确认包。9. 推送比特PSH:当发送端PSH=1时,接收端尽快的交付给应用进程。10. 复位比特(RST):当RST=1时,表明TCP连接中出现严重差错,必须释放连接,再重新建立连接。11. 同步比特SYN:在建立连接是用来同步序号。SYN=1, ACK=0表示一个连接请求报文段。SYN=1,ACK=1表示同意建立连接。12. 终止比特FIN:FIN=1时,表明此报文段的发送端的数据已经发送完毕,并要求释放传输连接。13. 窗口:用来控制对方发送的数据量,通知发放已确定的发送窗口上限。14. 检验和:该字段检验的范围包括首部和数据这两部分。由发端计算和存储,并由收端进行验证。15. 紧急指针:紧急指针在URG=1时才有效,它指出本报文段中的紧急数据的字节数。16. 选项:长度可变,最长可达40字节wireshark捕获到的TCP包中的每个字段如下图所示:

三. TCP三次握手

       TCP建立连接时,会有三次握手过程,如下图所示,wireshark截获到了三次握手的三个数据包。第四个包才是http的,说明http的确是使用TCP建立连接的。



下面来逐步分析三次握手过程:第一次握手:客户端向服务器发送连接请求包,标志位SYN(同步序号)置为1,序号为X=0



第二次握手:服务器收到客户端发过来报文,由SYN=1知道客户端要求建立联机。向客户端发送一个SYN和ACK都置为1的TCP报文,设置初始序号Y=0,将确认序号(Acknowledgement Number)设置为客户的序列号加1,即X+1 = 0+1=1, 如下图:



第三次握手:客户端收到服务器发来的包后检查确认序号(Acknowledgement Number)是否正确,即第一次发送的序号加1(X+1=1)。以及标志位ACK是否为1。若正确,服务器再次发送确认包,ACK标志位为1,SYN标志位为0。确认序号(Acknowledgement Number)=Y+1=0+1=1,发送序号为X+1=1。客户端收到后确认序号值与ACK=1则连接建立成功,可以传送数据了。



四. TCP四次挥手

       TCP断开连接时,会有四次挥手过程,如下图所示,wireshark截获到了四次挥手的四个数据包。



下面来逐步分析四次挥手过程:第一次挥手:客户端给服务器发送TCP包,用来关闭客户端到服务器的数据传送。将标志位FIN和ACK置为1,序号为X=1,确认序号为Z=1。



服务器收到FIN后,发回一个ACK(标志位ACK=1),确认序号为收到的序号加1,即X=X+1=2。序号为收到的确认序号=Z。



服务器关闭与客户端的连接,发送一个FIN。标志位FIN和ACK置为1,序号为Y=1,确认序号为X=2。



客户端收到服务器发送的FIN之后,发回ACK确认(标志位ACK=1),确认序号为收到的序号加1,即Y+1=2。序号为收到的确认序号X=2。




转自:tcp窗口滑动以及拥塞控制
http://blog.chinaunix.net/uid-26275986-id-4109679.htmlTCP协议作为一个可靠的面向流的传输协议,其可靠性和流量控制由滑动窗口协议保证,而拥塞控制则由控制窗口结合一系列的控制算法实现。

一. 滑动窗口协议

     关于这部分自己不晓得怎么叙述才好,因为理解的部分更多,下面就用自己的理解来介绍下TCP的精髓:滑动窗口协议。所谓滑动窗口协议,自己理解有两点:1. “窗口”对应的是一段可以被发送者发送的字节序列,其连续的范围称之为“窗口”;2. “滑动”则是指这段“允许发送的范围”是可以随着发送的过程而变化的,方式就是按顺序“滑动”。在引入一个例子来说这个协议之前,我觉得很有必要先了解以下前提:-1. TCP协议的两端分别为发送者A和接收者B,由于是全双工协议,因此A和B应该分别维护着一个独立的发送缓冲区和接收缓冲区,由于对等性(A发B收和B发A收),我们以A发送B接收的情况作为例子;
-2. 发送窗口是发送缓存中的一部分,是可以被TCP协议发送的那部分,其实应用层需要发送的所有数据都被放进了发送者的发送缓冲区;
-3. 发送窗口中相关的有四个概念:已发送并收到确认的数据(不再发送窗口和发送缓冲区之内)、已发送但未收到确认的数据(位于发送窗口之中)、允许发送但尚未发送的数据以及发送窗口外发送缓冲区内暂时不允许发送的数据;
-4. 每次成功发送数据之后,发送窗口就会在发送缓冲区中按顺序移动,将新的数据包含到窗口中准备发送;
     TCP建立连接的初始,B会告诉A自己的接收窗口大小,比如为‘20’:
     字节31-50为发送窗口



     A发送11个字节后,发送窗口位置不变,B接收到了乱序的数据分组:



     只有当A成功发送了数据,即发送的数据得到了B的确认之后,才会移动滑动窗口离开已发送的数据;同时B则确认连续的数据分组,对于乱序的分组则先接收下来,避免网络重复传递:


二. 流量控制

     流量控制方面主要有两个要点需要掌握。一是TCP利用滑动窗口实现流量控制的机制;二是如何考虑流量控制中的传输效率。
1. 流量控制
     所谓流量控制,主要是接收方传递信息给发送方,使其不要发送数据太快,是一种端到端的控制。主要的方式就是返回的ACK中会包含自己的接收窗口的大小,并且利用大小来控制发送方的数据发送:



     这里面涉及到一种情况,如果B已经告诉A自己的缓冲区已满,于是A停止发送数据;等待一段时间后,B的缓冲区出现了富余,于是给A发送报文告诉A我的rwnd大小为400,但是这个报文不幸丢失了,于是就出现A等待B的通知||B等待A发送数据的死锁状态。为了处理这种问题,TCP引入了持续计时器(Persistence timer),当A收到对方的零窗口通知时,就启用该计时器,时间到则发送一个1字节的探测报文,对方会在此时回应自身的接收窗口大小,如果结果仍未0,则重设持续计时器,继续等待。
2. 传递效率
     一个显而易见的问题是:单个发送字节单个确认,和窗口有一个空余即通知发送方发送一个字节,无疑增加了网络中的许多不必要的报文(请想想为了一个字节数据而添加的40字节头部吧!),所以我们的原则是尽可能一次多发送几个字节,或者窗口空余较多的时候通知发送方一次发送多个字节。对于前者我们广泛使用Nagle算法,即:
*1. 若发送应用进程要把发送的数据逐个字节地送到TCP的发送缓存,则发送方就把第一个数据字节先发送出去,把后面的字节先缓存起来;
*2. 当发送方收到第一个字节的确认后(也得到了网络情况和对方的接收窗口大小),再把缓冲区的剩余字节组成合适大小的报文发送出去;
*3. 当到达的数据已达到发送窗口大小的一半或以达到报文段的最大长度时,就立即发送一个报文段;
     对于后者我们往往的做法是让接收方等待一段时间,或者接收方获得足够的空间容纳一个报文段或者等到接受缓存有一半空闲的时候,再通知发送方发送数据。

三. 拥塞控制

     网络中的链路容量和交换结点中的缓存和处理机都有着工作的极限,当网络的需求超过它们的工作极限时,就出现了拥塞。拥塞控制就是防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。常用的方法就是:
1. 慢开始、拥塞控制
2. 快重传、快恢复
     一切的基础还是慢开始,这种方法的思路是这样的:
-1. 发送方维持一个叫做“拥塞窗口”的变量,该变量和接收端口共同决定了发送者的发送窗口;
-2. 当主机开始发送数据时,避免一下子将大量字节注入到网络,造成或者增加拥塞,选择发送一个1字节的试探报文;
-3. 当收到第一个字节的数据的确认后,就发送2个字节的报文;
-4. 若再次收到2个字节的确认,则发送4个字节,依次递增2的指数级;
-5. 最后会达到一个提前预设的“慢开始门限”,比如24,即一次发送了24个分组,此时遵循下面的条件判定:
*1. cwnd < ssthresh, 继续使用慢开始算法;
*2. cwnd > ssthresh,停止使用慢开始算法,改用拥塞避免算法;
*3. cwnd = ssthresh,既可以使用慢开始算法,也可以使用拥塞避免算法;
-6. 所谓拥塞避免算法就是:每经过一个往返时间RTT就把发送方的拥塞窗口+1,即让拥塞窗口缓慢地增大,按照线性规律增长;
-7. 当出现网络拥塞,比如丢包时,将慢开始门限设为原先的一半,然后将cwnd设为1,执行慢开始算法(较低的起点,指数级增长);



     上述方法的目的是在拥塞发生时循序减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够的时间把队列中积压的分组处理完毕。慢开始和拥塞控制算法常常作为一个整体使用,而快重传和快恢复则是为了减少因为拥塞导致的数据包丢失带来的重传时间,从而避免传递无用的数据到网络。快重传的机制是:
-1. 接收方建立这样的机制,如果一个包丢失,则对后续的包继续发送针对该包的重传请求;
-2. 一旦发送方接收到三个一样的确认,就知道该包之后出现了错误,立刻重传该包;
-3. 此时发送方开始执行“快恢复”算法:
*1. 慢开始门限减半;
*2. cwnd设为慢开始门限减半后的数值;
*3. 执行拥塞避免算法(高起点,线性增长);

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: