专栏首页IT笔记分享计算机网络协议

计算机网络协议

七层协定

越接近硬件的阶层为底层,越接近应用程序的层为高层。无论接收端还是发送端,每一阶层只认识对方的同一阶层数据。客户端通过应用程序将数据放入第七层,再将第七层数据打包到第六层,依次打包到第一层,然后传送给接收端,接收端主机由第一层开始,依序打开每个包,然后交给对应的阶层处理。

TCP/IP

TCP/IP 也是使用 OSI 七层协议的观念, 所以同 样具有分层的架构,只是将它简化为四层。

从图中可以发现,TCP/IP 将应用、表现、会谈三层整合成一个应用层,在 应用层上面可以实作的程序协议有 HTTP, SMTP, DNS 等等。 传送层则没有变,不过依 据传送的可靠性又将封包格式分为连接导向的 TCP 及非连接导向的 UDP 封包格式。网 络层也没有变,主要内容是提供了 IP 封包,并可选择最佳路由来到达目标 IP 地址。数据链结层与物理层则整合成为一个链结层,包括定义硬件讯号、 讯框转位串的编码 等等,因此主要与硬件 (不论是区网还是广域网) 有关。

TCP/IP运作过程

  1. 应用程序阶段:打开浏览器,在浏览器上面输入网址,按下 [Enter]。 此时网址与相关数据会被浏览器包成一个数据, 并向下传给 TCP/IP 的应用层;
  2. 应用层:由应用层提供的 HTTP 通讯协议,将来自浏览器的数据包起来,并给予一个应用层表头,再向传送层丢去;
  3. 传送层:由于 HTTP 为可靠联机,因此将该数据丢入TCP 封包内,并给予 一个 TCP 封包的表头,向网络层丢去;
  4. 网络层:将 TCP 包裹包进 IP 封包内,再给予一个 IP 表头 (主要就是来源与目标的 IP),向链结层丢去;
  5. 链结层:如果使用以太网络时,此时 IP 会依据 CSMA/CD 的标准,包裹到 MAC 讯框中,并给予 MAC 表头,再转成位串后, 利用传输媒体传送到远程主机 上。

TCP三次握手

  • A:封包发起 当客户端对服务器端联机时,就必须要送出一个要求联机的封包,此时客户端必须随机取用一个大于 1024 以上的端口来做为程序沟通的接口。然后在TCP 的表头当中,必须要带有 SYN 的主动联机(SYN=1),并且记下发送出联机封包给服务器端的序号 (Sequence number = 10001) 。
  • B:封包接收与确认封包传送 当服务器接到这个封包,并确定要接收这个封包后,就会制作一个同时带有SYN=1,ACK=1的封包,其中acknowledge的号码要给客户端确认用,所以该数字会比(A步骤)里面的Sequence号码多一号(ack=10001+1=10002),那我们服务器也必须要确认客户端确实可以接收我们的封包才行, 所以也会发送出一个 Sequence (seq=20001) 给客户端,并且开始等待客户端给我们服务器端的回应。
  • C:回送确认封包 当客户端接收到来自服务器端的aACK数字后(10002)就能够确认之前那个要求封包被正常的接收了,接下来如果客户端也同意与服务器端建立联机时,就会再次发送一个确认封包 (ACK=1) 给服务器,亦即是 acknowledge = 20001+1 = 20002。
  • D:取得最后的确认 若一切顺利,在服务器端收到带有ACK=1且ack=20002的封包后,就能建立起这次的联机了。

为什么TCP客户端最后还要发送一次确认呢?

主要防止已经失效的连接请求报文突然又传送到了服务器,从而产生错误。

如果使用的是两次握手建立连接,假设有这样一种场景,客户端发送了第一个请求连接并且没有丢失,只是因为在网络结点中滞留的时间太长了,由于TCP的客户端迟迟没有收到确认报文,以为服务器没有收到,此时重新向服务器发送这条报文,此后客户端和服务器经过两次握手完成连接,传输数据,然后关闭连接。此时此前滞留的那一次请求连接,网络通畅了到达了服务器,这个报文本该是失效的,但是,两次握手的机制将会让客户端和服务器再次建立连接,这将导致不必要的错误和资源的浪费。

如果采用的是三次握手,就算是那一次失效的报文传送过来了,服务端接受到了那条失效报文并且回复了确认报文,但是客户端不会再次发出确认。由于服务器收不到确认,就知道客户端并没有请求连接。

UDP协议

UDP和TCP不一样,UDP不提供可靠的传输模式,因为他不是面向连接的一个机制,因为在UDP的传输过程中,接收端在接收到封包后,不会回复响应封包(ACK)给发送端,所以封包并没有像TCP封包有较为严密的检查机制。UDP 可以在 Data 处填入更多的数据了。同时 UDP 比较 适合需要实时反应的一些数据流,例如影像实时传送软件等, 就可以使用这类的封包传送。

TCP连接释放(四次挥手)

  1. 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部,FIN=1,其序列号为seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),此时,客户端进入FIN-WAIT-1(终止等待1)状态。 TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。
  2. 服务器收到连接释放报文,发出确认报文,ACK=1,ack=u+1,并且带上自己的序列号seq=v,此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。
  3. 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。
  4. 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文,FIN=1,ack=u+1,由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。
  5. 客户端收到服务器的连接释放报文后,必须发出确认,ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。
  6. 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。

为什么客户端最后还要等待2MSL?

MSL(Maximum Segment Lifetime),TCP允许不同的实现可以设置不同的MSL值。

第一,保证客户端发送的最后一个ACK报文能够到达服务器,因为这个ACK报文可能丢失,站在服务器的角度看来,我已经发送了FIN+ACK报文请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个2MSL时间段内收到这个重传的报文,接着给出回应报文,并且会重启2MSL计时器。

第二,防止类似与“三次握手”中提到了的“已经失效的连接请求报文段”出现在本连接中。客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。

为什么建立连接是三次握手,关闭连接确是四次挥手呢?

建立连接的时候, 服务器在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。 而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,而自己也未必全部数据都发送给对方了,所以己方可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送,从而导致多了一次。

如果已经建立了连接,但是客户端突然出现故障了怎么办?

TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75分钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

参考文章:

https://blog.csdn.net/qzcsu/article/details/72861891

本文分享自微信公众号 - IT笔记分享(xiaosen_javashare),作者:xiaosen

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-02-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java多线程学习(五)——等待通知机制

    方法wait()的作用是使当前线程进行等待,wait()方法是Object类的方法,该方法用来将当前线程放到“预执行队列”,并在wait()所在的代码处停止执行...

    小森啦啦啦
  • Java多线程学习 (一)

    进程是操作系统运行程序的基本单位,是一次程序的执行。简单来说一个进程就是一个运行中的程序。

    小森啦啦啦
  • Java多线程学习(三)——synchronized(下)

    用关键字synchronized声明方法是有弊端的。比如线程A调用同步方法执行一个长时间任务,那么线程B就要等较长时间才能调用。

    小森啦啦啦
  • 做到这3点,你也能成为一个高情商的人

    几乎每个人都想做一个“高智商”、“高情商”的人,我也不例外——例外的是,我的智商和阿甘差不多,甚至很长一段时间内的我情商也不高,大学、高中、初中的同学对我“低情...

    沉默王二
  • 我的Python分析成长之路9

    统计分析是数据分析的重要组成部分,它几乎贯穿整个数据分析的流程。运用统计方法,将定量与定性结合,进行的研究活动叫做统计分析。而pandas是统计分析的重要库。

    py3study
  • OAuth2在内存、Redis、JDBC方式下的多客户端配置

    Spring所提供的OAuth2集成策略,支持多种方式存储认证信息以及客户端信息,由于在之前的文章中讲解使用时把知识点进行了拆分,有很多同学不太会组合使用,很多...

    恒宇少年
  • 「JAVA」细述合理创建字符串,分析字符串的底层存储,你不该错过

    什么是字符串?如果直接按照字面意思来理解就是多个字符连接起来组合成的字符序列。为了更好的理解以上的理论,我们先来解释下字符序列,字符序列:把多个字符按照一定的顺...

    老夫不正经
  • 零基础入门 13: UGUI Text

    前几篇介绍了UGUI里的Image,今天来说下UGUI 的Text,显示文本的组件。因为有了之前代码创建Image的铺垫,所以对Text的使用就都在这篇介绍了。

    韩东吉
  • 前端学习路线图鉴

    本文采用CC BY-NC-SA 3.0 Unported协议进行许可,转载请保留此文章链接

    Debug客栈
  • 码云小课堂 | 主流的开源协议有哪些?我们该如何选择?

    主流的开源协议有哪些?我们该如何选择? License是软件的授权许可,里面详尽表述了你获得代码后拥有的权利,可以对别人的作品进行何种操作,何种操作又是被禁止的...

    码云Gitee

扫码关注云+社区

领取腾讯云代金券