TCP/IP(五)传输层之细说TCP的三次握手和四次挥手

前言

  这一篇我将介绍的是大家面试经常被会问到的,三次握手四次挥手的过程。以前我听到这个是什么意思呀?听的我一脸蒙逼,但是学习之后就原来就那么回事!

一、运输层概述

1.1、运输层简介

  这一层的功能也挺简单的,运输层提供应用层提供端到端通信服务,通俗的讲,两个主机通讯,也就是应用层上的进程之间的通信,也就是转换为进程和进程之间的通信了,我们之前学到网络层,

  IP协议能将分组准确的发送到目的主机,但是停留在网络层,并不知道要怎么交给我们的主机应用进程,通过前面的学习,我们学习有mac地址,通过mac地址能找到同一个网络下主机,有IP地址,

  通过ip地址能找到不同网络下的网络,结合mac地址就能找到对应主机,那么怎么找到主机应用进程呢,肯定也有一个东西来标识它,那就是我们常说的端口了。

1.2、端口

  端口,占有16位,其大小也就有65536个,是从0~65535.也就是一台计算机有65535个端口,主机之间的通讯,也就是应用进程之间的通讯,都要依靠端口,一个进程对应一个端口

  进程A和进程B通信,进程A分到的端口为60000,进程B分到的端口为60001,进程A通过端口60000发送数据给进程B,就知道要交给60001端口,也就到了进程B中 ,这样就达到了通信的目的。

1.3、熟知端口、登记端口、客户端端口

  1)熟知端口:0-1023, 也就是一些固定的端口号,比如http使用的80端口,意思就是在访问网址时,我们访问服务器的端口就是80,然后服务器那边传网页的数据给我们。

  2)登记端口:1024-49151,比如微软开发了一个系统应用,该应用在通讯或使用时,需要使用到xxx端口,那么就要去登记一下这个端口,以免有别人公司的应用使用同一个端口号,

        例如,windows系统中的3389端口,就是用来实现远程连接的,就固定了这台计算机如果要使用远程连接服务,就打开3389端口,别人就能使用远程连接连你了,默认是不打开的。

  3)客户端端口:49152-65535,一般我们使用某个软件,比如QQ,等其他服务,随机拿这个范围内的端口,而不是去拿前面哪些固定的,拿到等通讯结束后,就会释放该端口。

知道了端口是什么?运输层具体做了什么事情呢?运输层就是将两个端口连起来通信的介质,不然光知道两个端口有什么用,怎么通信的,还是要靠运输层来做这个事情,其中重要的就是靠两个协议,UDP和TCP协议

二、UDP协议

  2.1、UDP概述

    UDP:User Datagram Protocol 用户数据报协议

    

  2.2、特点 

    无连接、不可靠

    无连接:意思就是在通讯之前不需要建立连接,直接传输数据

    不可靠:是将数据报的分组从一台主机发送到另一台主机,但并不保证数据报能够到达另一端,任何必须的可靠性都由应用程序提供。在 UDP 情况下,虽然可以确保发送消息的大小

        却不能保证消息一定会达到目的端。没有超时和重传功能,当 UDP 数据封装到 IP 数据报传输时,如果丢失,会发送一个 ICMP 差错报文给源主机。即使出现网络阻塞情况,

        UDP 也无法进行流量控制。此外,传输途中即使出现丢包,UDP 也不负责重发,甚至当出现包的到达顺序杂乱也没有纠正的功能。

  2.3、UDP报文格式

    UDP在IP报文中的位置如图所示:

    

    UDP报文格式如图所示:

    

    1)UDP首部  

      源端口号:占16位,源主机的应用进程所使用的端口号

      目标端口号:占16位,目标主机的应用进程所使用的端口号,也就是我们需要通信的目标进程

      UDP(包)报长度:UDP用户数据报的长度,数据部分+UDP首部之和为UDP报长度

      检验和:检验和是为了提供可靠的 UDP 首部和数据而设计,这里不要和上面的不可靠传输搞混淆了,这里提供可靠的UDP首部,是因为一个进程可能接受多个进程过来的报文,那么如何区分他们呢,

          就是通过5个东西来进行区分的, “源 IP 地址”、“目的 IP 地址”、“协议号”、“源端口号”、“目标端口号”的,这个检测可靠,是检测接受哪个正确的报文,也就是说是哪个报文要进这个端口。那个不可靠,

          说的是这个报文可能丢失,可能其中数据损坏了我们不关心,但是这些的前提是,你得传输到正确的目的地去,不然乱出乱发数据报,岂不是乱套了。

    2)UDP伪首部

      就是拿到IP层的一些数据,因为要进行检验和,就必须要有这些数据。其中检验的算法跟IP层中检验首部的办法是一样的。

      分析:

        

     一个目标进程中,其中的报文,目标端口,目标ip地址肯定都是一样的,但是源IP地址和源端口就可能不一样,这就说明了不同源而同一目的地的报文会定位到同一队列

      这跟接下来我们要讨论的TCP不一样,因为UDP是无连接的,大家都是用这一条通道,所以其队列中就会出现上面所说的这样的情况。

  2.4、使用UDP协议的例子

      在选择使用协议的时候,选择UDP必须要谨慎。网络质量令人十分不满意的环境下,UDP协议数据包丢失会比较严重。但是由于UDP的特性:它不属于连接型协议,因而具有资源消耗小,

    处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。比如我们聊天用的ICQ和QQ就是使用的UDP协议。

    1)应用层协议中DNS,也就是根据域名解析ip地址的一个协议,他使用的就是UDP

    2)DHCP,这个是给各电脑分配ip地址的协议,其中用的也是UDP协议

    3)IGMP,我们说的多播,也就是使用的UDP,在多媒体教师,老师拿笔记本讲课,我们在下面通过各自的电脑看到老师的画面,这就是通过UDP传输数据,所以会出现有的同学卡,

      有的同学很流畅,就是因为其不可靠传输,但是卡一下,对接下来的观看并没有什么映像。

三、TCP协议

3.1、TCP协议概述

  百度上说:

    

  TCP协议是面向连接的、可靠传输、有流量控制,拥塞控制,面向字节流传输等很多优点的协议。其最终功能和UDP一样,在端和端之间进行通信,但是和UDP的区别还是很大的。

3.2、TCP协议功能 

  1)当应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,TCP则把数据流分割成适当长度的报文段,最大传输段大小(MSS)通常受该计算机连接的网络的数据链路层的最大传送单元(MTU)限制。

    之后TCP把数据包传给IP层,由它来通过网络将包传送给接收端实体的TCP层
  2)TCP为了保证报文传输的可靠,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);

    如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传
      在数据正确性与合法性上,TCP用一个校验和函数来检验数据是否有错误,在发送和接收时都要计算校验和;同时可以使用md5认证对数据进行加密。
      在保证可靠性上,采用超时重传和捎带确认机制。
      在流量控制上,采用滑动窗口[1] 协议,协议中规定,对于窗口内未经确认的分组需要重传。
  3)在拥塞控制上,采用广受好评的TCP拥塞控制算法(也称AIMD算法)。该算法主要包括三个主要部分:1)加性增、乘性减;2)慢启动;3)对超时事件做出反应。

3.3、TCP报文结构

  

  1)源端口号

  2)目标端口号

  3)序列号:因为在TCP是面向字节流的,他会将报文都分成一个个字节,给每个字节进行序号编写,比如一个报文有900个字节组成,那么就会编成1-900个序号,然后分几部分来进行传输,

        比如第一次传,序列号就是1,传了50个字节, 那么第二次传,序列号就为51,所以序列号就是传输的数据的第一个字节相对所有的字节的位置

  4)确认应答:如刚说的例子,第一次传了50个字节给对方,对方也会回应你,其中带有确认应答,就是告诉你下一次要传第51个字节来了,所以这个确认应答就是告诉对方要传第多少个字节

  5)首部长度:就是首部的长度,

  6)保留:给以后有需要在用,这个保留的位置放的东西是跟控制位类似的

  7)控制位:目前有的控制位为6个

    URG:紧急,当URG为1时,表名紧急指针字段有效,标识该报文是一个紧急报文,传送到目标主机后,不用排队,应该让该报文尽量往下排,让其早点让应用程序给接受。

    ACK:确认,当ACK为1时,确认序号才有效。当ACK为0时,    确认序号没用

    PSH:推送,当为1时,当遇到此报文时,会减少数据向上交付,本来想应用进程交付数据是要等到一定的缓存大小才发送的,但是遇到它,就不用在等足够多的数据才向上交付,

        而是让应用进程早点拿到此报文,这个要和紧急分清楚,紧急是插队,但是提交缓存大小的数据不变,这个推送就要排队,但是遇到他的时候,会减少交付的缓存数据,提前交付。

    RST:复位,报文遇到很严重的差错时,比如TCP连接出错等,会将RST置为1,然后释放连接,全部重新来过。

    SYN:同步,在进行连接的时候,也就是三次握手时用得到,下面会具体讲到,配合ACK一起使用

    FIN:终止,在释放连接时,也就是四次挥手时用的。

  8)窗口:指发送报文段一方的接受窗口大小,用来控制对方发送的数据量(从确认号开始,允许对方发送的数据量)。也就是后面需要讲的滑动窗口的窗口大小

  9)检验和:检验首部和数据这两部分,和UDP一样,需要拿到伪首部中的数据来帮助检测

  10)选项:长度可变,介绍一种选项,最大报文段长度,MSS。 能够告诉对方TCP,我的缓存能接受报文段的数据字段的最大长度是MSS个字节。如果没有使用选项,那么首部固定是20个字节。

  11)填充:就是为了让其成为整数个字节

3.4、面向连接(三次握手)

  面向连接(三次握手):在通信之前,会先通过三次握手的机制来确认两端口之间的连接是否可用。而UDP不需要确认是否可用,直接传

  三次握手机制:

       

  一开始客户端和服务端都是关闭状态,但是在某个时刻,客户端需要和服务端进行通信,此时双方都会各自准备好端口,服务器段的端口会处于监听状态,等待客户端的连接

  客户端可会知道自己的端口号,和目的进程的端口号,这样才能发起请求。

  第一次握手:客户端想与服务器进行连接了,所以状态变为主动打开,同时发送一个连接请求报文给服务器段SYN=1,并且会携带x个字节过去。

        发送完请求连接报文后,客户端的状态就变为了SYN_SENT,可以说这个状态是等待发送确认(为了发送第三次握手时的确认包)

  第二次握手:服务端接收到连接请求报文后,从LSTTEN状态变为被动打开状态,然后给客户端返回一个报文。这个报文有两层意思,一是确认报文,而可以达到告诉客户端,我也打开连接了。

        发完后,变为SYN_RCVD状态(也可以说是等待接受确认状态,接受客户端发过来的确认包)

  第三次握手:客户端得到服务器端的确认和知道服务器端也已经准备好了连接后,还会发一个确认报文到服务器端,告诉服务器端,我接到了你发送的报文,接下来就让我们两个进行连接了。

        客户端发送完确认报文后,进入ESTABLISHED,而服务器接到了,也变为ESTABLISHED。

 3.5、同时打开连接请求

  正常情况下,通信一方请求建立连接,另一方响应该请求,但是如果出现,通信双方同时请求建立连接时,则连接建立过程并不是三次握手过程,而且这种情况的连接也只有一条,并不会建立两条连接。

  同时打开连接时,两边几乎同时发送 SYN,并进入 SYN_SENT 状态,当每一端收到 SYN 时,状态变为 SYN_RCVD,同时双方都再发 SYN 和 ACK 作为对收到的 SYN 进行确认应答。

  当双方都收到 SYN 及相应的 ACK 时,状态变为 ESTABLISHED 

  

3.6、可靠传输

 通过1)数据编号和积累确认 2)以字节为单位的滑动窗口 3)超时重传时间 4)快速重传 这四个方面来达到可靠传输的目的。

  1)、数据编号:将每个字节进行编号,有900个字节,就从1到900进行编号

     积累确认:服务器端不是接收到一个字节就发一个确认,那样效率太低,而是当接收到4,5个时,在发送一个确认,那么在之前的确认之前的数据就算发送成功了的。

  2)滑动窗口:这个跟在数据链路层讲个滑动窗口一样。每次能发送的数据是在此窗口中的,接到了多少数据,就往后滑多少数据

  3)超时重传时间:这个也在链路层讲过,如果等待一段时间后,还没接收到确认报文,那么就重新传

  4)快速重传:在滑动窗口中的应用,比如传了1234 6到服务器端,老办法是在4之后的所有数据度要重新传,而这个快速重传就只需要等待传了5这个序号,就可以继续往下接收数据了。

3.7、流量控制

  在传输层中,有接受缓存和发送缓存这两个东西的存在,所以每次发送数据过去另一端时,都会把这些数据给带过去,让对方知道自己的这两个缓存的大小,然后来合理的设置自己的发送窗口的大小

  如果对方的缓存快满了,对方在传送数据过来的时候,就会告诉自己,少发一点数据过来,自己就设置滑动窗口小一点,让对方有缓冲的机会,而不会导致缓存溢出,不让自己的报文被丢弃。

3.8、堵塞控制

  其实跟流量控制差不多,但是站的角度更大,此时既考虑了对方接收不过来,缓存太多溢出导致,又考虑在线路中,线路上的传输速率就那么大,但是有很多人同时用,发送的数据太多,就会使线路发现拥塞

  也就是路由器可能转发不过来,导致大量数据丢失,这两个问题。所以拥塞控制这个解决方案,大概意思就是当检测到有网络拥塞时,就会让自己的滑动窗口变小,但具体是怎么变化的,就是根据算法来算了,

    发送窗口的上限值 = Min[rwnd,cwnd]    

    rwnd:接受窗口,根据接受缓存,而定的接受窗口,接收缓存还有很多,那么接收窗口就大

    cwnd:拥塞窗口,根据线路中的拥塞状况来决定,线路中不拥塞,那么此窗口就大,

    发送窗口是取两个中较小值。这个还是可以理解的。

  慢启动算法、快速恢复算法、结合来达到对拥塞进行控制的。

3.9、TCP释放连接(四次挥手)

  通信完成后,连接就会被释放,通过四次挥手机制来完成这个事情。

  

  

  第一次挥手:从ESTABLISHED变为主动关闭状态,客户端主动发送释放连接请求给服务器端,FIN=1。发送完之后就变为FIN_WAIT_1状态,这个状态可以说是等待确认状态。

  第二次挥手:服务器接收到客户端发来的释放连接请求后,状态变为CLOSE_WAIT,然后发送确认报文给客户端,告诉他我接收到了你的请求。为什么变为CLOSE_WAIT,原因是是客户端发送的释放连接请求,

        可能自己这端还有数据没有发送完呢,所以这个时候整个TCP连接的状态就变为了半关闭状态。服务器端还能发送数据,并且客户端也能接收数据,但是客户端不能在发送数据了,只能够发送确认报文。

        客户端接到服务器的确认报文后,就进入了FIN_WAIT_2状态。也可以说这是等待服务器释放连接状态。

  第三次挥手:服务器端所有的数据度发送完了,认为可以关闭连接了,状态变为被动关闭,所以向客户端发送释放连接报文,发完之后自己变为LAST_WAIT状态,也就是等待客户端确认状态

  第四次挥手:客户端接到释放连接报文后,发送一个确认报文,然后自己变为TIME_WAIT,而不是立马关闭,因为客户端发送的确认报文可能会丢失,丢失的话服务器就会重传一个FIN,也就是释放连接报文,

        这个时候客户端必须还没关闭。 当服务器接受到确认报文后,服务器就进入CLOSE状态,也就是关闭了。但是由于上面说的这个原因,客户端必须等待一定的时间才能够进入CLOSE状态。

3.10、同时关闭连接

  正常情况下,通信一方请求连接关闭,另一方响应连接关闭请求,并且被动关闭连接。但是若出现同时关闭连接请求时,通信双方均从 ESTABLISHED 状态转换为 FIN_WAIT_1 状态。

  任意一方收到对方发来的 FIN 报文段后,其状态均由 FIN_WAIT_1转变到 CLOSING 状态,并发送最后的 ACK 数据段。当收到最后的 ACK 数据段后,状态转变化 TIME_WAIT,

  在等待 2MSL 时间后进入到 CLOSED 状态,最终释放整个 TCP 传输连接。其过程入下:

  

总结:一般需要保证数据可靠时,都会使用tcp协议:http协议进行网站的访问时,使用的就是tcp。

 

喜欢就“推荐”哦!

posted @ 2017-09-29 16:36  华仔Coding  阅读(4469)  评论(4编辑  收藏  举报
levels of contents