前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TCP/IP(五)传输层之细说TCP的三次握手和四次挥手

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

作者头像
用户1195962
发布2018-01-18 16:03:42
1K0
发布2018-01-18 16:03:42
举报
文章被收录于专栏:LanceToBigDataLanceToBigData

前言

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

一、运输层概述

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。

喜欢就“推荐”哦!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-09-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、运输层概述
    • 1.1、运输层简介
      • 1.2、端口
        • 1.3、熟知端口、登记端口、客户端端口
        • 二、UDP协议
          •   2.1、UDP概述
            •   2.2、特点 
              •   2.3、UDP报文格式
                •   2.4、使用UDP协议的例子
                • 三、TCP协议
                  • 3.1、TCP协议概述
                    • 3.2、TCP协议功能 
                      • 3.3、TCP报文结构
                        • 3.4、面向连接(三次握手)
                          •  3.5、同时打开连接请求
                            • 3.6、可靠传输
                              • 3.7、流量控制
                                • 3.8、堵塞控制
                                  • 3.9、TCP释放连接(四次挥手)
                                    • 3.10、同时关闭连接
                                    领券
                                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档