计算机网络TCP、HTTP总结

计算机网络

TCP、UDP

一、TCP首部结构详解
TCP数据封装在一个IP数据报中如图
在这里插入图片描述

TCP数据在IP数据包中的封装
下图是TCP报文数据格式。TCP首部如果不计选项和填充字段,它通常是20个字节

在这里插入图片描述

TCP数据在IP数据包中的封装
  • 源端口和目的端口: 各占2字节(16位)这两个值加上IP首部中的源端IP地址和目的端IP地址唯一确定一个TCP连接。有时一个IP地址和一个端口号也称为socket。
  • 序号: 占4个字节(32位),是本报文段所发送的数据项目组第一个字节的序号。在TCP传送的数据流中,每一个字节都有一个序号。例如,一报文段的序号为100,而且数据共100字节,则下一个报文段的序号就是200。序号是32位的无符号数,序号到达2^32-1 后从0开始。
  • 确认序号: 占4字节(32位),是期望收到对方下次发送的数据的第一个字节的序号,也就是期望收到的下一个报文段的首部中的序号。确认序号应该是上次已成功收到数据字节序号+1。只有ACK标志为1时,确认序号才有效
  • 确认序号: 占4字节(32位),是期望收到对方下次发送的数据的第一个字节的序号,也就是期望收到的下一个报文段的首部中的序号。确认序号应该是上次已成功收到数据字节序号+1。只有ACK标志为1时,确认序号才有效
  • 数据偏移: 占4位,表示数据开始的地方离TCP段的起始处有多远。实际上就是TCP段首部的长度。由于首部长度不固定因此数据偏移字段是必要的。数据偏移以4字节(32位)为长度单位。因此TCP首部的最大长度是60(15 * 4)个字节。
  • 保留: 6位,供以后应用,现在置为0。
  • 6个标志位比特:
    • URG: 当URG=1时,注解此报文应尽快传送,而不要按本来的列队次序来传送。与“紧急指针”字段共同应用,紧急指针指出在本报文段中的紧急数据的最后一个字节的序号,使接管方可以知道紧急数据共有多长。
    • ACK: 当ACK=1时,确认序号字段才有效。
    • PSH: 当PSH=1时,接收方应该尽快将本报文段立即传送给其应用层。
    • RST: 当RST=1时,表示出现连接错误,必须释放连接,然后再重建传输连接。复位比特还用来拒绝一个不法的报文段或拒绝打开一个连接。
    • SYN: SYN=1,ACK=0时表示请求建立一个连接,携带SYN标志的TCP报文段为同步报文段。
    • FIN: 发端完成发送任务,并关闭发送数据。
  • 16位窗口: TCP通过滑动窗口的概念来进行流量控制。设想在发送端发送数据的速度很快而接收端接收速度却很慢的情况下,为了保证数据不丢失,显然需要进行流量控制,协调好通信双方的工作节奏。所谓滑动窗口,可以理解成接收端所能提供的缓冲区大小。TCP利用一个滑动的窗口来告诉发送端对它所发送的数据能提供多大的缓冲区。窗口大小为字节数,起始于确认序号字段指明的值(这个值是接收端正期望接收的字节)。窗口大小是一个16位字段,因而窗口大小最大为65535字节。
  • 检验和: 检验和覆盖了整个TCP报文段、TCP首部和数据。这是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。
  • 紧急指针: 只有当URG标志置1时紧急指针才有效。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。

二、TCP三次握手过程

在这里插入图片描述

TCP三次握手过程图
  1. 客户端向服务器发出连接请求报文,这时报文首部中的同部位SYN=1,同时选择一个初始序列号 seq=x。此时TCP客户端进程进入了SYN-SENT(同步已发送状态)状态。TCP规定,SYN报文段(SYN=1的报文段)不能携带数据,但需要消耗掉一个序号。

  2. TCP服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1确认号是ack=x+1,同时也要为自己初始化一个序列号 seq=k。此时TCP服务器进程进入了SYN-RCVD(同步收到)状态。这个报文也不能携带数据,但是同样要消耗一个序号。

  3. TCP客户进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=k+1,[自己的序列号seq=J+1]。此时TCP连接建立,客户端进入ESTABLISHED(已建立连接)状态。TCP规定,ACK报文段可以携带数据,但是如果不携带数据则不消耗序号。

    当服务器收到客户端的确认后也进入ESTABLISHED状态,此后双方就可以开始通信了。

关于TCP三次握手的问题

  1. 为什么需要三次握手?首先我们要知道信道是不可靠的,但是我们要建立可靠的连接发送可靠的数据,也就是数据传输是需要可靠的。在这个时候三次握手是一个理论上的最小值,并不是说是tcp协议要求的,而是为了满足在不可靠的信道上传输可靠的数据所要求的。

    在《计算机网络》一书中其中有提到,三次握手的目的是“为了防止已经失效的连接请求报文段突然又传到服务端,因而产生错误”。

    这种情况是:一端(client)A发出去的第一个连接请求报文并没有丢失,而是因为某些未知的原因在某个网络节点上发生滞留,导致延迟到连接释放以后的某个时间才到达另一端(server)B。

    本来这是一个早已失效的报文段,但是B收到此失效的报文之后,会误认为是A再次发出的一个新的连接请求,于是B端就向A又发出确认报文,表示同意建立连接。如果不采用“三次握手”,那么只要B端发出确认报文就会认为新的连接已经建立了,但是A端并没有发出建立连接的请求,因此不会去向B端发送数据,B端没有收到数据就会一直等待,这样B端就会白白浪费掉很多资源。

    如果采用“三次握手”的话就不会出现这种情况,B端收到一个过时失效的报文段之后,向A端发出确认,此时A并没有要求建立连接,所以就不会向B端发送确认,这个时候B端也能够知道连接没有建立。

  2. 为什么需要三次握手?三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。

    第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常
    第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常。
    第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常

    所以三次握手就能确认双发收发功能都正常,缺一不可。

三、TCP四次挥手过程

在这里插入图片描述

TCP四次挥手过程
  1. 客户端进程发出连接释放报文,并且停止发送数据。释放数据报文首部FIN=1。其序列号为seq=x(等于前面已经传送过来的数据的最后一个字节的序号加1)此时,客户端进入FIN-WAIT-1(终止等待1)状态。TCP规定,FIN报文段即使不携带数据,也要消耗一个序号。

  2. 服务器收到连接释放报文,发出确认报文ACK=1 ack=x+1,并且带上自己的序列号seq=v。此时,服务端就进入了CLOSE-WAIT(关闭等待)状态。TCP服务器通知高层的应用进程,客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。

  3. 客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文(在这之前还需要接受服务器发送的最后的数据)。

  4. 服务器将最后的数据发送完毕后,就向客户端发送连接释放报文FIN=1 ACK=1 ack=x+1 seq=k。由于在半关闭状态,服务器很可能又发送了一些数据,假定此时的序列号为seq=w,此时,服务器就进入了LAST-ACK(最后确认)状态,等待客户端的确认。

TCP四次挥手问题

  1. 为什么需要四次挥手?
    为了确保数据能够完成传输。关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了。但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

  2. 释放连接时为什么TIME-WAIT状态必须等待2MSL时间?MSL是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。

    ①为了保证A发送的最后一个ACK报文能够到达B。这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认。B会超时重传这个FIN+ACK报文段,而A就能在2MSL时间内收到这个重传的FIN+ACK报文段,重置时间等待计时器(2MSL)。如果A在TIME-WAIT状态不等待一段时间,而是在发送完ACK报文段后就立即释放连接就无法收到B重传的FIN+ACK报文段,因而也不会再发送一次确认报文段。这样,B就无法按照正常的步骤进入CLOSED状态。

    ②A在发送完ACK报文段后,再经过2MSL时间,就可以使本连接持续的时间所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求的报文段。

  3. 客户端突然挂掉了怎么办?正常连接时,客户端突然挂掉了,如果没有措施处理这种情况,那么就会出现客户端和服务器端出现长时期的空闲。解决办法是在服务器端设置保活计时器,每当服务器收到客户端的消息,就将计时器复位。超时时间通常设置为2小时。若服务器超过2小时没收到客户的信息,他就发送探测报文段。若发送了10个探测报文段,每一个相隔7.5秒,还没有响应就认为客户端出了故障,因而终止该连接。

  4. TCP协议如何保证可靠传输?

    1. 应用数据被分割成TCP认为最适合发送的数据块
    2. TCP给发送的每一个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层
    3. 校验和机制:TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到段的检验和有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
    4. TCP的接收端会丢弃重复的数据
    5. 流量控制(TCP利用滑动窗口实现流量控制): TCP连接的每一方都有固定大小的缓冲空间,TCP的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP使用的流量控制协议是可变大小的滑动窗口协议
    6. 拥塞控制: 当网络拥塞时,减少数据的发送。
    7. ARQ协议: 也是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组。
    8. 超时重传: 当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段。

四、TCP流量、网络拥塞控制、计时器

  1. 流量控制:TCP利用滑动窗口实现流量控制。流量控制是为了控制发送方发送速率,保证接收方来得及接收。接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为0,则发送方不能发送数据。

  2. 拥塞控制:在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫拥塞。拥塞控制就是为了防止过多的数据注入到网络中,这样就可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及到所有的主机,所有的路由器,以及与降低网络传输性能有关的所有因素。相反,流量控制往往是点对点通信量的控制,是个端到端的问题。流量控制所要做到的就是抑制发送端发送数据的速率,以便使接收端来得及接收。

    TCP发送方可能因为IP网络的拥塞而被遏制,TCP拥塞控制就是为了解决这个问题。
    为了进行拥塞控制,TCP发送方要维持一个拥塞窗口(cwnd)的状态变量。拥塞控制窗口的大小取决于网络的拥塞程度,并且动态变化。发送方让自己的发送窗口取为拥塞窗口和接收方的接受窗口中较小的一个。

    TCP拥塞控制的几种方法:慢启动,拥塞避免,快重传和快恢复。

    • 慢启动: 慢开始算法的思路是当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么可能会引起网络阻塞,因为现在还不知道网络的符合情况。经验表明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。cwnd初始值为1,每经过一个传播轮次,cwnd加倍。
      为了防止拥塞窗口cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量。慢开始门限ssthresh的用法如下: 当 cwnd < ssthresh 时,使用上述的慢开始算法。 当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。 当 cwnd = ssthresh 时,既可使用慢开始算法,也可使用拥塞控制避免算法。

    • 拥塞避免: 拥塞避免算法的思路是让拥塞窗口cwnd缓慢增大,即每经过一个往返时间RTT就把发送放的cwnd加1。

    • 快重传与快恢复: 在TCP/IP中,快速重传和恢复(Fast Retransmit And Recovery,FRR)是一种拥塞控制算法,它能快速恢复丢失的数据包。没有FRR,如果数据包丢失了TCP将会使用定时器来要求传输暂停。在暂停的这段时间内,没有新的或复制的数据包被发送。有了FRR,如果接收机接收到一个不按顺序的数据段,它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认,它会假定确认件指出的数据段丢失了,并立即重传这些丢失的数据段。有了FRR,就不会因为重传时要求的暂停被耽误。当有单独的数据包丢失时,快速重传和恢复(FRR)能最有效地工作。当有多个数据信息包在某一段很短的时间内丢失时,它则不能很有效地工作。

  3. TCP的四种定时器:

    • 重传计时器(Retransmission Timer): TCP是保证数据可靠传输的,怎么保证呢?那就是带确认的重传机制。在滑动窗口协议中,接受窗口会在连续收到的包序列中的最后一个包向接收端发送一个ACK,当网络拥堵的时候,发送端的数据包和接收端的ACK包都有可能丢失。

      TCP为了保证数据可靠传输,就规定在重传的“时间片”到了以后,如果还没有收到对方的ACK,就重发此包,以避免陷入无限等待中

      当TCP发送报文段时,就创建该特定报文的重传计时器。可能发生两种情况:
      ①若在计时器截止时间到之前收到了对此特定报文段的确认,则撤销此计时器。
      ②若在收到了对此特定报文段的确认之前计时器截止时间到,则重传此报文段,并将计时器复位。

    • 坚持计时器(Persistent Timer): 专门对付零窗口通知而设立的。发送端向接收端发送数据包知道接受窗口填满了,然后接受窗口告诉发送方接受窗口填满了停止发送数据。此时的状态称为“零窗口”状态,发送端和接收端窗口大小均为0,直到接受TCP发送确认并宣布一个非零的窗口大小,但这个确认会丢失。==在TCP中对确认是不需要发送确认的。若确认丢失,接受的TCP端并不知道,而是认为他已经完成了任务,并等待着发送TCP发送更多的报文段。但发送TCP并没有收到确认,就等待对方发送确认来通知窗口大小。双方TCP就一直在等待对方,就造成了一种死锁状态。==要打开这种死锁,TCP为每一个连接使用一个持久计时器。当发送TCP收到窗口大小为0的确认时,就坚持启动计时器。当坚持计时器期限到时,发送TCP就发送一个特殊的报文段,叫做探测报文。通过探测报文来是双方的窗口重新打开。

    • 保活计时器(Keeplive Timer):保活计时器使用在某些现实中,用来防止在两个TCP之间的连接出现长时间的空闲。假定客户打开了到服务器的连接,传送了一些数据,然后就保持静默了。也许这个客户出故障了。在这种情况下,这个连接将永远的处理打开状态。要解决这种问题,在大多数的实现中都是使服务器设置保活计时器。每当服务器收到客户的信息,就将计时器复位,通常设置为两小时。若服务器过了两小时还没有收到客户的信息,他就发送探测报文段。若发送了10个探测报文段(每一个像个75秒)还没有响应,就假定客户除了故障,因而就终止了该连接

    • 时间等待计时器(Timer_Wait Timer):时间等待计时器是在四次挥手的时候使用的。四次挥手的简单过程是这样的,假设客户端准备中断连接,首先向服务器端发送一个FIN的请求关闭包(FIN=FINAL然后由ESTABLISHED过渡到FIN-WAIT1状态。

      服务器收到FIN包以后会发送一个ACK,然后自己由ESTABLISHED进入CLOSE-WAIT。此时通信进入半双工状态,即留给服务器一个机会将剩余数据传递给客户端,传递完后服务器发送一个FIN+ACK的包,表示我已经发送完数据可以断开连接了,就这便进入LAST_ACK阶段。

      客户端收到以后,发送一个ACK表示收到并同意请求,接着由FIN-WAIT2进入TIME-WAIT阶段。服务器收到ACK,结束连接。

      此时(即客户端发送完ACK包之后),客户端还要等待2MSL(MSL=maxinum segment lifetime最长报文生存时间,2MSL就是两倍的MSL)才能真正的关闭连接。


TCP与UDP协议区别

在这里插入图片描述

TCP、UDP协议对比图

UDP在传送数据之前不需要先建立连接,远地主机在收到UDP报文后,不需要给出任何确认。虽然 UDP不提供可靠交付,但在某些情况下UDP确是一种最有效的工作方式(一般用于即时通信)。比如:微信语音、直播视频等等。

TCP提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。 TCP不提供广播或多播服务。由于TCP要提供可靠的,面向连接的传输服务(TCP的可靠体现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接用来节约系统资源),这一难以避免增加了许多开销,如确认,流量控制,计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多处理机资源。TCP一般用于文件传输、发送和接收邮件、远程登录等场景。

HTTP相关

1.HTTP状态码

类别原因短语
1XXInformational 信息性状态码接受的请求正在处理中
2XXSuccess 成功状态码请求正常处理完成
3XXRedirection 重定向状态码需要进行附加操以作完成请求
4XXClient Error 客户端错误状态码请求的资源不存在/服务器无法处理请求/请求语法错误
5XXServer Error 服务器错误状态码服务器处理请求出错(500程序处理异常 502网关异常)

2.HTTP长连接与短连接
在HTTP/1.0中默认使用短连接。 也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。

而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:Connection:keep-alive

在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接需要客户端和服务端都支持长连接。

HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。

3.HTTP是无状态协议,如果保存用户状态?
HTTP是一种不保存状态,即无状态(stateless)协议。也就是说HTTP协议自身不对请求和响应之间的通信状态进行保存,那么我们保存用户状态呢?

答案就是Session,Session机制的存在就是为了解决这个问题,Session的主要作用就是通过服务端记录用户的状态。 典型的场景是购物车,当你要添加商品到购物车的时候,系统不知道是哪个用户操作的,因为HTTP协议是无状态的。服务端给特定的用户创建特定的Session之后就可以标识这个用户并且跟踪这个用户了(一般情况下,服务器会在一定时间内保存这个 Session,过了时间限制,就会销毁这个Session)。

在服务端保存Session的方法很多,最常用的就是内存和数据库(比如是使用内存数据库redis保存)。既然Session存放在服务器端,那么我们如何实现Session跟踪呢?大部分情况下,我们都是通过在 Cookie中附加一个Session ID来方式来跟踪。==Cookie被禁用怎么办?==当Cookie被禁用,最常用的就是利用URL重写把Session ID直接附加在URL路径的后面。

4.HTTP跟HTTPS的区别

  • 端口: HTTP默认使用的是80端口,HTTPS使用的是443端口
  • 安全性和性能:
    • HTTP协议运行在TCP之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份,不安全。
    • HTTPS是运行在SSL/TLS之上的HTTP协议,SSL/TLS运行在TCP之上。所有传输的内容都经过加密加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。
    • HTTP安全性没有HTTPS高,但是HTTPS比HTTP耗费更多服务器资源。

对称加密:密钥只有一个,加密解密为同一个密码,且加解密速度快,典型的对称加密算法有DES、AES等。
非对称加密:密钥成对出现(且根据公钥无法推知私钥,根据私钥也无法推知公钥),加密解密使用不同密钥(公钥加密需要私钥解密,私钥加密需要公钥解密),相对对称加密速度较慢,典型的非对称加密算法有RSA、DSA等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值