计算机网络相关知识复习

一、概述

计算机网络体系结构的几种模型如下图所示:

其中OSI模型(Open System Interconnection Reference Model,OSI),全名“开放式系统互联通信参考模型”,OSI只是理论上的模型,并没有成熟的产品;TCP/IP是一个四层的体系结构,在实际中综合了OSI和TCP/IP的优点,采用一种只有五层协议的体系结构。

体系分层的优点有:1. 各层之间是独立的,可以实现相对独立的功能;2. 灵活性好,当某一层发生变化时,只要层间接口关系保持不变,其他层不会受到影响; 3. 结构上可分割开; 4. 易于实现和维护; 5. 能促进标准化工作。

五层协议简介:

  1. 应用层:

    1. 应用层是体系结构的最高层,任务就是通过应用进程间的交互来完成特定网络应用,应用层的协议定义的是应用进程间通信和交互的规则。
    2. 主要来规定应用程序的数据格式,消除固有数据格式和网络标准数据格式直接的差异,因为在网络流中数据的格式是标准化的,但是到不同的设备、操作系统上,所要求数据的呈现格式是不同的,因此需要转化成统一的、用户能够感知的声音、图片等。我们把应用层交互的数据单元称为报文(message)。
  2. 运输层:

    1. 运输层的任务就是负责向两台主机中进程之间的通信提供通用的数据传输服务 (建立端口到端口之间的通信)。所谓通用就是多种应用可以使用同一个运输层服务。
    2. 由于一台主机可同时运行多个进程,因此运输层有复用和分用,复用就是应用层中多个进程同时使用一个运输层的服务,分用就是运输层把收到的信息交付上面应用层中的相应进程。
    3. 运输层主要有两种协议:TCP(传输控制协议,通过面向连接的、可靠的数据传输服务,数据传输单位是报文段)和UDP(用户数据报协议,提供无连接的、尽最大努力的数据传输服务,但不保证数据传输的可靠性,数据传输单位是用户数据报)。
  3. 网络层:网络层负责为分组交换网上的不同主机提供通信服务。发送数据时,网络层把运输层产生的报文段(TCP)或用户数据报(UDP)封装成分组或包进行传送,这些分组也叫IP数据报。

  4. 数据链路层:又称链路层。两台主机之间的数据传输总是在一段一段的链路上进行的,所以需要专门的链路层协议。在两个相邻节点之间传送数据时,数据链路层将网络层交下来的IP数据报组成帧,在两个相邻节点上传送。(在数据链路层上也能进行检错和纠错)

  5. 物理层:在物理层上所传数据的单位是比特(bit),主要负责传送0和1。考虑到需要证明在传输媒体上传输数据比特流,而不是指具体的传输媒体。物理层的作用是尽可能屏蔽传输媒体和通信手段的差异,使数据链路层感觉不到这些差异。

  6. OSI模型的会话层、表示层、应用层:

    1. 会话层:负责建立、管理和终止表示层实体之间的通信会话;
    2. 表示层:提供各种用于应用层数据的编码和转换功能,确保一个系统的应用层发送的数据能被另一个系统的应用层识别。
    3. 应用层:最靠近用户的一层,是为计算机用户提供应用接口,也为用户直接提供各种网络服务。

下图为应用进程的数据在各层之间的传递过程中所经历的变化,假设两台主机通过一台路由器连接起来。

注意:路由器在转发分组时只用到了网络层,没有用到运输层和应用层。

二、物理层

三、数据链路层

  1. WIFI属于数据链路层;
  2. 局域网

四、网络层

网络层向上只提供简单灵活的、无连接的、尽最大努力交付的数据报服务,不提供服务质量的承诺。

1、网际协议IP(Internet Protocol)

1、IP数据报的格式


IP数据报如上图所示,由首部和数据两部分组成。首部中固定的各字段如下:

  1. 版本:占4位,指IP协议的版本。通信双方使用的IP协议的版本必须一致;
  2. 首部长度:4位,顾明思议,记录首部的长度。因为IP首部基本为20字节,所以这个值为0101;
  3. 区分服务:8位,只有在使用区分服务时,这个字段才起作用;
  4. 总长度:指首部和数据之和的长度,占16位,因此数据报的最大长度为2^16-1=65535字节,实际上这样长度的数据包在现实中极少遇到,因为在IP层下面的每一种数据链路层协议都规定了一个数据帧中的数据字段的最大长度,称为最大传送单元MTU,最常用的以太网就规定其MTU值为1500字节;IP数据报越短,路由器转发速度就越快,为此IP协议规定,互联网中的所有主机和路由器必须能够接受长度不超过576字节的数据包,若发送超过576字节的话,需要进行分片;
  5. 标识:16位,一个计数器,相同的标识字段的值使分片后的各数据报片最后能正确地重装成为原来的数据报。
  6. 标志:2位,只有前两位有意义:
    1. 最低位MF=1表示还有分片,MF=0表示这已是若干数据报片中的最后一个;
    2. 中间的一位DF,意思为不能分片,只有当DF=0时才允许分片
  7. 片偏移:13位,较长的分组在分片后,某片在原分组中的相对位置。
  8. 生存时间:TTL(Time To Live),表明这是数据报在网络中的寿命。由发出数据报的源点设置这个字段,其目的是防止无法交付的数据报无限制地在互联网中兜圈子,白白浪费网络资源。单位是跳数,路由器在每次转发数据报之前就把TTL值减1;若减小到零,就丢弃这个数据报,不再转发。
  9. 协议:指出此数据报携带的数据是使用何种协议,以便使目的主机的IP层知道应将数据部分上交给哪个协议进行处理。
  10. 首部校验和:值校验数据报的首部,但不包含数据部分。

2、IP地址分类如下图所示:

从图中可以看到,A、B、C类地址的网络号字段分裂为1个、2个、3个字节长,网络号字段的最前面有1-3位的类别为,其数值分别规定为0, 10, 110;

  1. A类地址:默认子网掩码255.0.0.0,网络号的第一位必须为0,但是由于ip地址 0.0.0.0 和ip地址127.0.0.1分别表示本网络、环回地址,所以ip地址的范围为1.0.0.0-127.0.0.0,私有地址范围为:10.0.0.0-10.255.255.255,或者记为10.0.0.0/8,又称24位块。若主机发送一个目的地址为127.0.0.1的ip数据报,则本主机中的协议软件就会处理数据报中的数据,不会把数据报发送到任何网络,也就是说目的地址为环回地址永远不会出现在任何网络上;

  2. B类地址:默认子网掩码255.255.0.0, 网络号的前两位必须为10,由于128.0.0.0是不能够被指派的,所以ip地址的范围为128.1.0.0-191.255.255.255;私有地址范围为172.16.0.0-172.31.255.255,或者记为172.16.0.0/12,又称20位块;

  3. C类地址:默认子网掩码255.255.255.0,网络号的前三位必须为110,由于192.0.0.0不能够被指派,所以其ip地址范围为192.0.1.0-223.255.255.255,私有地址范围为:192.168.0.0-192.168.255.255,或者记为192.168.0.0/16,又称为16位块。

注:子网掩码是用于与ip地址进行&运算,以判断ip地址的子网号和其主机号。物理地址是数据链路层和物理层使用的地址,而IP地址是网络层和以上各层使用的地址,是一种逻辑地址。

随着IP地址的消耗完,采用CIDR对IP地址进行划分,CIDR把32位的IP地址划分为前后两个第部分,前面部分为网络前缀,后半部分指明主机,比如128.24.123.23/21,前21位代表此ip地址的网络前缀,前缀后面的11位代表主机号。

2、地址解析协议ARP

ARP解决的问题:已经知道一个机器(主机或者路由器)的IP地址,需要找出其相应的硬件地址。其作用如下图所示:

ARP协议的要点:由于网络层使用的是IP地址,在实际网络的链路上传送数据帧时,最终还是要必须使用该网络的硬件地址(MAC)。地址解析协议ARP解决这个问题的方法就是在主机ARP高速缓存中存放一个从IP地址到硬件地址的映射表,并且这个映射表还经常动态更新(新增或超时删除)。


协议工作流程:当主机A要向本局域网中的某台主机B发送IP数据报时,就先在其ARP高速缓存中查看是否有主机B的IP地址,如果有的话,就在ARP高速缓存中查出其对应的硬件地址,再把这个硬件地址写入MAC帧,然后通过局域网把该MAC帧发往此硬件地址;如果其ARP高速缓存中不存在主机B IP地址与硬件地址的映射,则其按照以下步骤找出主机B的硬件地址:

  1. 主机A的ARP进程在本局域网上广播一个ARP请求分组,主要内容是:“我的IP地址是x.x.x.x,硬件地址是x-x-x-x-x-x,我想知道IP地址(也就是主机B的ip地址)为y.y.y.y的主机的硬件地址”;

  2. 在本局域网上的所有主机运行的ARP进程都将收到此ARP请求分组;

  3. 主机B发现此请求中要查询的IP地址一致,就收下这个ARP分组(此ARP请求分组中携带的也有主机A的硬件地址,主机B会更新自己的ARP高速缓存中主机A的硬件地址),并向主机A发送ARP响应分组,同时在这个响应分组中写入自己的硬件地址(其他主机不做响应)。注:ARP请求分组是广播发送的,ARP响应分组是普通的单播;

  4. 主机A收到主机B的ARP响应分组后,就在其ARP高速缓存内写入主机B的IP地址与硬件地址的映射,然后主机A就可以向主机B发送MAC帧了。

请注意:ARP是解决同一个局域网中的主机或路由器的IP地址和硬件地址的映射问题,如果两个主机不在同一个局域网上,需要通过路由器进行转发。

3、路由器转发流程

路由器的路由表内每一条路由主要由(目的网络地址,下一跳地址),使用子网划分后,路由表必须包含目的网路地址、子网掩码、下一跳地址。分组转发算法如下:

  1. 从数据报的首部提取目的主机的IP地址D,得出目的网络地址N;
  2. 若N的就是与此路由器直接相连的某个网络,则进行直接交付,不需要再经过其他的路由器,直接把数据交付给目的主机(这里包括把目的主机地址D转换为具体的硬件地址,把数据报封装为MAC帧,再发送此帧);否则就是间接交付,执行3;
  3. 若路由表中有目的地址为D的特定主机路由,则把数据报传送给路由表中所指明的下一跳路由器;否则执行4;
  4. 若路由表中有到达网络N的路由,则把数据报传送给路由表中所指明的下一跳路由器;否则执行5;
  5. 若路由器表中有一个默认路由,则把数据传送给路由表中所指明的默认路由器;否则报告转发分组出错。

4、ping与ICMP协议

ICMP协议:为了更有效的转发IP数据报和提高交付成功的机会,在网络层使用了网际控制报文协议ICMP(Internet Control Message Protocol),ICMP允许主机或路由器报告差错情况和提供有关异常情况的报告。ICMP报文封装在IP数据报中,作为其中的数据部分,所以在使用ICMP报文的时候必须添加上IP数据头。

ICMP的一个重要的应用就是分组网间探测PING(Packet Internet Groper),用来测试两台主机之间是否可以通信。PING使用了ICMP回送请求与回送回答报文。PING是应用层直接使用网络层的ICMP的一个例子,没有通过运输层的TCP或UDP。

假设主机A PING主机B,过程:

  1. 主机A首先会建立一个ICMP回应请求数据包,主机B的IP地址为目的地址,主机A的IP地址为源地址;
  2. 主机A会通过主机B的IP地址和子网掩码判断是否与自己在同一个网络;如果是的话,就会在本机的ARP高速缓存内寻找主机B的硬件地址,如果找到,就将此硬件地址写入到MAC帧,然后直接发送给主机B;如果找不到的话,就在局域网内发送一个ARP请求分组,以获得主机B的MAC地址,然后进行后续操作;
  3. 如果主机B和主机A不在同一个网段,就需要交给网关处理(就是找到网关的MAC地址,至于怎么得到,也是和之前ARP解析一样的操作方法),然后通过路由找到主机B。查找过程如3所述。
  4. 主机B接收后检查该数据帧,将IP数据包从帧中提取出来,交给本层的IP协议层。IP层检查后,将有用的信息提取交给ICMP协议,后者处理后,构建一个ICMP应答包,发送给主机A。

对ping后返回信息的分析

  1. Request timed out:对方已关机,或者网络上没有这个地址;对方与自己不在同一网段内,通过路由也无法到达
    对方存在,不过设置了ICMP数据包过滤(比如防火墙设置)。
  2. Destination host Unreachable:自己未设定默认路由,对方跟自己不在同已网段;网线有问题
  3. Bad ip address:没有连接到DNS服务器,无法解析IP,也可能是IP不存在
  4. Source quench received:对方或中途服务器繁忙而无法应答
  5. Unkonw host:远程主机的名字不能被域名服务器转换成IP地址,故障原因可能是DNS服务器有故障,或者名字不正确,或者网络管理员的系统与远程主机之间的通信线路故障。
  6. No answer: 无响应。说明本地系统有一条通向中心主机的路由,但却接收不到它发给该中心主机的人呢和信息。故障原因可能是:中心主机没有工作;本地或中心主机网络配置不正确;本地或中心的路由器没有工作;通信线路有故障;中心主机存在路由选择问题。
  7. Ping 127.0.0.1:如果ping不通,则表明本地址TCP/IP协议不能正常工作
  8. no rout to host:网卡工作不正常
  9. transmit failed error code:10043网卡驱动不正常
  10. unknown host name: DNS配置不正确

5、虚拟专用网VPN和网络地址转换NAT

由于全球IP地址资源的紧缺,一个机构能申请到的IP地址远远小于本机构所拥有的主机数。RFC指明了一些专用地址,这些地址只能用于一个机构的内部通信,而不能用于和互联网上的主机通信。这样的一个机构使用的网络称为专用网。

  • 10.0.0.0 ~ 10.255.255.255
  • 172.16.0.0 ~ 172.31.255.255
  • 192.168.0.0 ~ 192.168.255.255

1、虚拟专用网络VPN

VPN(Virtual Private Network)如下图所示,同一个机构相隔较远的两个场所A和B,现在这两个场所需要通过公共的互联网构成一个VPN,这种VPN称为内联VPN。假如X要与Y通信时,会先发送数据包到R1上,R1会对其进行加密,然后重新加上数据的首部,再通过互联网进行传输;R2收到后对其解密,然后交付给Y。这个过程就好像发生在隧道内一样。

还有一种VPN称为远程接入VPN,员工可以通过拨号接入互联网,使得员工个人的电脑和公司的主机之间建立VPN隧道,因而外地员工与公司通信的内容也是保密的,员工们感到好像就是使用公司内部的本地网络。

2、网络地址转换NAT

NAT(Netword Address Translation)是解决专用网内部的主机与互联网上的主机通信的问题,因为专用网内部的IP地址都是不能够被互联网上的路由器转发的。网络地址转换NAT需要在专用网连接到互联网的路由器上安装NAT软件,装有NAT软件的路由器叫做NAT路由器,它至少有一个外部全球IP地址。
工作原理如下:在图中,专用网192.168.0.0内所有主机的IP地址都是本地IP地址192.168.x.x。NAT路由器至少有一个全球IP地址才能和互联网通信(当然也可能有很多个)。为了更加有效地利用NAT路由器上的全球IP地址,现在常用的NAT转换把传输层的端口号也利用上。

五、传输层

  1. 从通信和信息处理来看,运输层向它上面的应用层提供通信服务,属于面向通信部分的最高层,同时也是用户功能中的最底层;
  2. 网络层为两台主机之间提供逻辑通信,而运输层为应用进程之间提供端到端的逻辑通信。
  3. 网络层的IP数据报首部中的检验和字段,只检验首部是否出现差错而不检查数据部分。

1、TCP与UDP

UDP在传送数据之前不需要首先建立连接,远地主机的运输层在收到UDP报文后,不需要给出任何确认;虽然UDP不可靠交付,但在某些情况下UDP却是一种最有效的工作方式。

而TCP则提供面向连接的服务,在传送数据之前必须先建立连接,数据传送结束后要释放连接。由于TCP是面向连接的服务, 所以不可避免的增加了很多的开销,如确认、流量控制、计时器以及连接管理等。

1.1 端口

虽然通信的终点是应用进程,但只要把所传送的报文交到目的主机的某个合适的目的端口,剩下的工作(即交付目的进程)就由TCP或UDP来完成。不同的端口对应不同的应用进程。

1.2 用户数据报协议,UDP

用户数据报协议UDP只在IP的数据包服务之上增加了很少的功能,复用、分用和差错检测,其主要特点是:

  1. UDP是无连接的,即发送数据之前不需要建立连接,因此减少了开销和发送数据之前的延迟;
  2. UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的连接状态;
  3. UDP是面向报文的,发送方和接收方的UDP对上层和下层传过来的报文即不合并也不拆分,只对首部进行处理后交付,所以是面向单个报文的,同时这个报文的长度必须是合适大小的。
  4. UDP没有拥塞控制 ,因此网络出现的拥塞不会使源主机的发送效率降低,这对某些实时应用是很重要的。
  5. UDP支持一对一、一对多、多对一和多对多的交互通信,也就是说支持广播和多播;
  6. UDP的首部开销很小;

UDP用户数据包首部中校验和在计算时,要在UDP用户数据包之前增加12个字节的伪首部,这些伪首部并不是UDP用户数据报真正的首部,所以既不向下传也不向上交付。

1.3 传输控制协议,TCP

TCP最主要的特点:

  1. TCP是面向连接的,也就是说在使用TCP协议之前必须先建立连接(三次握手);在传送数据完毕后,必须释放已经建立的TCP连接(四次挥手)。
  2. 每一条TCP连接只能有两个端点,且只能是点对点的。是通过套接字(ip:port)建立的。
  3. TCP提供可靠交付的服务,通过TCP连接传送的数据,无差错、不丢失、不重复,并且按序到达
  4. TCP提供全双工通信,TCP允许通信双方的应用进程在任何时候都能发送数据。TCP连接的两端设有发送缓存和接收缓存,用来临时存放双向通信的数据。在发送时,应用进程把数据传送给TCP的缓存后就可以做自己的事情,而TCP在合适的时候把数据发送出去;在接收时,TCP把收到的数据放入缓存,上层的应用程序在合适的时候读取缓存中的数据。
  5. 面向字节流,TCP中的流指的是流入到进程或从进程留出的字节序列。“面向字节流”的含义是,虽然应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序交下来的数据仅仅看成是一串无结构的字节流,TCP并不知道所传送的字节流的含义。

1.3.3 TCP与UDP比较(SKK面经)

  1. 特点方面的比较:TCP是面向连接的,而UDP是无连接的;TCP提供可靠的交付,保证顺序、不丢包,而UDP是不可靠的,只能提供最大努力的交付,不保证数据的顺序;TCP是面向字节流的,而UDP是面向数据包的。
  2. 使用场景方面的比较:TCP适合传输大量数据、对可靠性要求较高的场合;UDP适合传输少量数据、对可靠性要求不高的场景,能够广播或多播,适合处理速度快的,比如直播、实时游戏、视频通话等。
  3. 使用UDP和TCP协议的各种应用和应用层协议:
    TCP:
    端口号    协议      协议名称
    21        FTP      文件传输协议
    22        SSH      用于连接服务器
    23        TELNET   用于远程登陆
    25        SMTP     简单邮件传输协议
    110       POP3     和SMTP对应,用于接收邮件
    80        HTTP     超文本传输协议
    443       HTTPS    
    UDP:
    68/67     DHCP     动态主机配置协议,客户端使用68,服务端使用67
    53        DNS      域名解析系统
    69        TFTP     简单文件传输协议
    161       SNMP     简单网络管理协议
    
  4. QQ里视频聊天用到了UDP,文件传输用到了TCP

2、TCP可靠传输、流量控制、拥塞控制

在进行下面的实现之前,首先对TCP报文段的首部格式相关字段进行说明:

  1. 序号seq:占四个字节,指的是本报文段所发送数据的第一个字节的序号;
  2. 确认号ack:占四个字节,指的是期望收到对方下一个报文段的第一个数据字节的序号;若确认号为N,则表明到序号N-1为止的所有数据都已经正确收到;
  3. 确认ACK:仅当ACK=1时确认号字段才有效,TCP规定,在建立连接后所有传送的报文段都必须把ACK置为1。
  4. 同步SYN:在连接建立时用来同步序号,当SYN=1而ACK=0时,表明这是一个连接请求报文段;对方若同意建立连接,则在响应报文段中使用SYN=1和ACK=1。
  5. 终止FIN:用来释放一个连接,当FIN=1时,表明此报文段的发送方的数据已经发送完毕,并要求释放运输连接。

2.1 流量控制和拥塞控制的实现

流量控制与拥塞控制的关系密切,但是也存在着一些差别:

  • 拥塞控制:就是防止过多的数据注入到网络中,可以使用网络中的路由器或链路不致过载,是一个全局性的过程。拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷。
  • 流量控制:往往指的是点对点通信量的控制,是个端对端的问题(接收端控制发送端)。流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。主要通过滑动窗口实现流量控制。

2.1.1 滑动窗口

一般来说,我们总是希望数据传输得更快一些,但如果把发送方数据发送的过快,接收方就有可能来不及接收,这就会造成数据的丢失。接收端在发送ACK确认的时候会带上缓冲区的窗口大小,从而流量控制:在TCP协议的报头信息中,有一个16位字段的窗口大小,窗口内容实际上是接收端接收数据后缓冲区的剩余大小(接收窗口)。接收端会在确认应答发送ACK报文时,将自己的接收窗口大小填入,并跟随ACK报文一起发送过去。而发送方根据ACK报文里的窗口大小的值的改变进而改变自己的发送速度。如果接收到窗口的大小值为0,那么发送方将停止发送数据。并且TCP为每一个连接设置一个持续计时器,只要TCP连接的一方收到对方的零窗口通知,就启动计时器,若持续计时器设置的时间到期,发送端就会发送一个探测报文段(携带1字节的数据),从而去获得接收方的接收窗口大小,打破死锁。

滑动窗口的实现:

滑动窗口实现流量控制。首先明确,TCP是双工的协议,会话的双方都可以同时接收和发送数据。TCP会话的双方都各自维护一个发送窗口和一个接收窗口。各自的接收窗口大小取决于应用、系统、硬件的限制。各自的发送窗口则要取决于接收端的接收窗口。因为TCP是全双工,所以两边都有滑动窗口。滑动窗口包括发送窗口和接收窗口。

如上图所示的发送端A:

  • 小于P1的都是已经发送并收到确认的部分,而大于P3的是不允许发送的部分;
  • P3-P1=A的滑动窗口;
  • P2-P1=已发送但尚未收到确认的字节数
  • P3-P2=允许发送但当前尚未发送的字节数(又称可用窗口或有效窗口)

请注意,接收端B只能对按序收到的数据中的最高序号给出确认,因此图中此时B发送的确认号为31。现在假定B收到了序号为31的数据,并把序号为31-33的数据交付给主机,然后B删除了这些数据,接着把接收窗口向前移动3个序号,同时给A发送了确认,窗口大小仍为20、确认号是34(表明B已经收到了截止到序号33为止的数据)。我们注意到序号为37、38、40的数据未按序收到,所以只能暂时存在接收窗口中。如下图所示,当A收到B的确认之后,就把发送窗口向前滑动了3个序号,但指针P2不动,A的可用窗口增大。

当A发送完序号为42-53的数据后,指针P2与P3重合,发送窗口内的序号都已经用完,但是还未收到确认。存在以下可能性:B已经收到数据并发送了确认,但是由于网络原因,并未收到确认。此时A的发送窗口为0,必须停止发送。为了保证可靠传输,A需要在一段时间后(由超时计数器控制)就重传这部分数据(已发送未收到确认),重新设置超时计时器,直到收到B的确认为止。如果A收到确认号落在发送窗口内,那么A就可以使发送窗口继续向前滑动,并发送新的数据。

为了满足以上,TCP的发送缓存和接收缓冲提供帮助:

  1. 发送缓存用来暂时存放:应用程序传送给发送方TCP准备发送的数据;TCP已经发送出但尚未收到确认的数据;
  2. 接收缓存用来暂时存放:按序到达的、但尚未被接收方应用程序读取的数据未按序到达的数据

2.1.2 拥塞控制

在某段时间内,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫做拥塞。

TCP进行拥塞控制的算法有四种,即慢开始(slow-start)、拥塞避免(congestion advoidance)、快重传(fast retransmit)和快恢复(fast recovery)

如上图所示,拥塞窗口是发送方维持的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口。发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就可以再增大一些,以便把更多的分组发送出去,但只要出现拥塞或有可能出现拥塞,就必须把拥塞窗口减小一些,以减少注入到网络中的分组数,所以拥塞窗口的作用就是控制发送速率的,避免发送的过多。判断网络是否拥塞的依据就是出现了超时。

  1. 慢开始:TCP开始发送时设置cwnd=1,不要一开始就发送大量的数据,先探测一个网络的拥塞程度,由小到大成倍增加拥塞窗口。发送方每收到一个对新报文段的确认就使发送方的拥塞窗口加1,因此使用慢开始算法后,每经过一个传输轮次,拥塞窗口cwnd就加倍。如上图中的慢开始阶段。传输轮次:把拥塞窗口所允许发送的报文段都连续发送出去,并收到了对已发送的最后一个字节的确认,也即往返时间RTT。

  2. 拥塞避免:为了防止cwnd增长过大引起网络拥塞,还需要设置一个慢开始门限ssthresh状态变量。当cwnd < ssthresh时,使用慢开始算法;当cwnd > sshthresh时,停止使用慢开始算法而改用拥塞避免算法;当两者相等时,使用两者算法中的一个即可。拥塞避免算法的思路就是让拥塞窗口cwnd缓慢地增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是像慢开始阶段那样加倍增长。

  3. 无论是慢开始阶段还是拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是有没有收到确认,又叫超时重传),就把慢开始门限sshthresh设置成出现拥塞时拥塞窗口(发送窗口)大小的一半。然后把拥塞窗口设置为1,重新执行慢开始算法。

  4. 当拥塞窗口=16时(图中的点4),出现了一个新的情况,就是发送方一连收到3个对同一个报文段的重复确认(记为3-ACK,假设接收方收到了6,8,9,显然会知道7丢失了,于是连续发送了4个对6的确认,其中后3个都是重复确认),于发送方立即进行重传(即“快重传”)。那么此时发送方的门限值sshthresh调整为当前拥塞窗口的一半(点5),同时设置拥塞窗口cwnd=sshthresh=8,并开始执行拥塞避免算法(即“快恢复”)。快重传和快恢复一定是要配合使用的。

  5. 发送窗口的上限值=min(接收窗口rwnd, 拥塞窗口cwnd)。

2.2 TCP可靠传输的实现

有了上面流量控制和拥塞控制,总结一下如何保证可靠传输:

  1. 校验和:如下图所示:
  2. 序列号:TCP传输时会为每个字节的数据都进行编号,这就是序列号,能够保证数据有序提交给应用层;
  3. 确认机制:TCP首部的确认号ack是期望收到下一个报文段的第一个字节的序号。假如接收方收到按序到达的一串数据时,会应答按序到达的最后一个序列号,表明这之前的都收到了,累计确认;
  4. 重传机制(超时重传、冗余ACK):
    1. 超时重传:TCP每发送一个报文段就会对这个报文段设置一次计时器,只要计时器设置的重传时间到期还没有收到确认的话,就要重传这一报文段;拥塞控制图中的2
    2. 冗余ACK(冗余确认):超时触发重传存在的一个问题就是超时周期往往太长。TCP规定每当比期望序号大的失序报文段到达时,发送一个冗余ACK,指明下一个期待字节的序号。比如拥塞控制图中的快重传阶段,当发送方收到对同一个报文段的3个冗余ACK时,就可以认为这个被确认报文段之后的报文段已经丢失,需要进行重传,这种技术被称为快重传。
  5. 流量控制:
  6. 拥塞控制:
  7. 三次握手、四次挥手:

2.3 TCP相关问题

参考: 浏览器输入URL到显示网页全过程.md
三次握手:

四次挥手:

2.4 SOCKET编程

网络层的IP地址可以唯一 标识网络中的主机;传输层的“协议+端口”可以唯一标识主机中的应用程序(进程);这样就可以使用三元组(ip地址, 协议, 端口)唯一标识网络中的进程。网络中需要互相通信的进程,就可以利用这个标志在他们之间进行交互。

  1. 什么是socket?在计算机通信领域,socket被翻译成“套接字”,是计算机之间进行通信的一种约定或一种方式。简单来说就是网络中进程之间通过socket进行通信。

  2. socket的基本操作:

    1. socket函数:定义如下所示,用于创建一个网络连接,或者说打开一个网络文件。
      // 函数返回值为文件描述符,有了文件描述符就可以使用普通的文件操作函数来传输数据了(读写);
      // af为IP地址类型,常用的有AF_INET和AF_INET6;type为套接字的类型,常用的有
      // SOCK_STREAM和SOCKET_DGRAM(面向连接的套接字tcp和面向无连接的套接字udp);                                
      // protocol表示传输协议,常用的有TCP传输协议和UDP传输协议。
      int socket(int af, int type, int protocol);
      // 分别表示创建TCP套接字和UDP套接字
      int tcp_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
      int udp_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
      
    2. bind函数:定义如下所示, socket函数创建完套接字、确定套接字的各种属性,然后用bind函数将套接字与特定的IP地址和端口绑定起来,只有这样,流经该IP地址和端口的数据才能交给套接字处理。类似的,客户端需要用connect函数建立连接。
      // sockfd为socket文件描述符;
      // addr为sockaddr结构体变量的指针,其中指明了需要绑定的IP地址和端口号;
      // addelen为addr变量的大小,可由sizeof计算出
      int bind(int sockfd, struct sockaddr *addr, socklen_t addrlen);
      // connect函数是客户端用来与服务器端建立连接的函数,参数含义与bind一样
      // 客户端不用绑定,系统会自动分配一个端口号和自身的IP地址组合
      int connect(int sockfd, struct sockaddr *addr, socklen_t addrlen);
      
    3. listen函数:对于服务端程序程序来说,使用bind绑定完套接字后,还需要使用listen函数让套接字进入被动监听状态,再调用accept函数,就可以随时响应客户端的请求。
      // 通过listen函数可以让套接字进入被动监听状态,所谓被动监听,就是指当前没有客户端
      // 请求时,套接字处于“睡眠”状态,只有当接收到客户端的请求时,套接字才会被“唤醒”来响应请求。
      // sock为需要进入监听状态的套接字,backlog为请求队列的最大长度。当套接字正在处理客
      //户端请求时,如果有新的请求进来,套接字是没有办法进行处理的,只能把它放进缓冲区,
      //待当前请求处理完毕后,再从缓冲区中读取出来。如果不断有新的请求进来,它们就按照先
      //后顺序在缓冲区中排队,直到缓冲区满。这个缓冲区就称为请求队列。请求队列的大小由backlog设置
      int listen(int sock, int backlog);
      
    4. accept函数: 当套接字处于监听状态时,可以通过accept函数来接收客户端的请求。需要注意的是,listen只是让套接字进入监听状态,并没有真正接收客户端请求,listen后面的代码会继续执行,直到遇到accept函数,accept函数会阻塞程序执行,直到有新的请求到来。
      // 参数与bind中是一样的,accept返回一个新的套接字来和客户端通信,addr保存了客户端的IP地址和端口号,sock是服务端的套接字。
      int accept(int sock, struct sockaddr *addr, socklen_t addrlen)
      
    5. 两台计算机建立连接后,在服务端使用write函数向套接字写入数据,客户端就能收到,然后再使用read函数从套接字中读取出来,就完成了一次通信。
  3. TCP服务器依次调用socket()、bind()、listen()之后,就会监听指定的socket地址了;TCP客户端依次调用socket()、connect()之后就向TCP服务器发送了一个连接请求。TCP服务器监听到这个请求之后,就会调用accept函数去接收请求,这样连接就建立好了。

  4. 通常服务器在启动的时候都会绑定一个周知的地址(如ip地址+端口号),用于提供服务,客户就可以通过它来接连服务器;而客户端就不用指定,有系统自动分配一个端口号和自身的ip地址组合。这就是为什么通常服务器端在listen之前会调用bind(),而客户端就不会调用,而是在connect()时由系统随机生成一个。

六、应用层

1、 域名系统DNS

作用就是将边长的域名解析成定长的IP地址。解析过程如下:当某一个应用程序需要把主机名解析为IP地址时,该应用就调用解析程序,并成为DNS的一个客户,把待解析的域名放在DNS请求报文中,以UDP用户数据报方式发送给本地域名服务器(使用UDP是为了减少开销,占用的端口号是53)。本地域名服务器在查找域名后,把对应的IP地址放在回答报文中返回。应用进程获得目的主机的IP地址后即可进行通信。

  1. 四种域名服务器:
    1. 根域名服务器:是最高层次的域名服务器,也是最重要的域名服务器。所有的根域名服务器都知道所有的顶级域名服务器的域名和IP地址。不管哪一个本地域名服务器,只要自己无法解决域名,就首先求助于根域名服务器(距离本地域名服务器最近的根域名服务器)。
    2. 顶级域名服务器:这些域名服务器负责管理在该顶级域名服务器注册的所有二级域名。当收到DNS查询请求时,就给出响应的回答(可能是最终的IP地址,也可能是下一步应当查找的域名服务器的IP地址)。
    3. 权限域名服务器:负责一个区的域名服务器,当一个权限域名服务器还不能给出最后的查询时,就会告诉发出查询请求的DNS客户,下一步应该找哪一个权限域名服务器。
    4. 本地域名服务器:本地域名服务器并不属于上图中的域名服务器层次结构,但是它对域名系统非常重要。当一台主机发出DNS查询请求时,这个查询请求报文就发送给本地域名服务器。
  2. 两种查询:
    1. 递归查询:一般主机向本地域名服务器查询使用的就是递归查询,当本地域名服务器不知道主机所要查询域名的IP地址时,本地域名服务器就以DNS客户的身份,向其他根域名服务器查询,而不是让该主机自己进行下一步的查询。所以递归查询的结果要么是域名对应的IP地址,要么无法查询到所需的IP地址。
    2. 迭代查询:本地域名服务器向根域名服务器查询通常采用的是迭代查询。当根域名服务器收到来自本地域名服务器的查询请求后,要么给出所要查询的IP地址,要么告诉本地域名服务器下一步应该查询的域名服务器的IP地址,即让本地域名服务器自己进行后续的查询;一般根域名服务器给出的都是顶级域名服务器,而顶级域名服务器也是执行迭代查询的规则。当然本地域名服务器也可以进行递归查询(根据最初查询请求报文的设置)。
  3. 实际中DNS的解析过程:
    1. 首先检查浏览器DNS缓存;
    2. 检查本地host文件、本地DNS缓存;
    3. 向DNS域名服务器查询:先向本地域名服务器查询,若本地域名服务器不能回答该请求(没有缓存),依次向根域名服务器(返回顶级域名服务器的IP地址)、顶级域名服务器(返回权限域名服务器IP地址)、权限域名服务器(返回所要查询目的主机的IP地址)发出迭代查询。
    4. 缓存结果
    5. 浏览器得到域名对应的IP地址,进行后续的访问。

2、文件传送协议FTP

FTP的控制连接(与客户端建立请求)使用21号端口,数据连接(将客户端所需的文件传送过去)使用20号端口,采用的是TCP;

TFTP使用69号端口,可用于UDP环境。

3、超文本传送协议HTTP

用户在点击鼠标链接某个万维网文档时,HTTP协议首先要和服务器建立TCP连接,这需要三次握手。当建立TCP连接的三报文握手的前两部分完成后(即经过了一个RTT时间),万维网客户就把HTTP请求报文,作为建立TCP连接的三报文握手中的第三个报文的数据,发送给万维网服务器。服务器收到HTTP请求报文后,就把所请求的文档作为响应报文返回给客户。从下图中可以看出,请求一个万维网文档所需的时间是该文档的传输时间(与文档大小成正比)加上两倍往返时间RTT(一个RTT用于连接TCP连接,另一个RTT用于请求和接收万维网文档。)

3.1 基础知识

HTTP, 超文本传输协议,是一种建立在TCP上的无状态的连接。基本工作流程是客户端发送一个HTTP请求,说明客户端想要访问的资源和请求的动作,服务端收到请求之后,开始处理请求访问服务器资源,最后通过发送HTTP响应把结果返回给客户端。

对于HTTP来说,主要有以下几个特点:

  1. 无状态,HTTP是一种无状态协议,它唯一知道的就是客户端会向服务端发送请求,而服务器则会向客户端返回响应,并且后续发生的请求对之前发生过的请求一无所知。所以若后续需要处理前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。
  2. 无连接:HTTP协议本身是无连接的,虽然使用了TCP连接,但是通信的双方在交换HTTP报文之前不需要先建立连接。含义就是限制每次连接只处理一个请求,服务器处理完客户的请求、并收到客户的应答后,即断开连接。长连接短连接是针对TCP连接来说的,HTTP是基于请求/响应模式的,因此只要服务端给了响应,本次HTTP连接就结束了。
  3. 媒体独立:只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。

HTTP是个无状态的协议,所以需要在请求头和响应头中表明自身的一些信息和想要执行的动作,这样,对方在收到信息后,就可以知道自己的身份以及想要干什么。
HTTP请求:客户端向服务器发送的HTTP请求由状态行、请求头、请求正文三部分组成。

  1. 状态行:即上图中的第一行,包括请求方法(GET、POST);URL地址(要从互联网上获得的资源定位符);HTTP协议版本号
  2. 请求头:图片中的4所描述
    1. Accept:客户端告诉服务端自己能够接收的MIME类型是什么;
      1. MIME(Multipurpose Internet Mail Extensions)是描述消息内容类型的因特网标准,MIME消息能包含文本,图像、音频、视频以及其他应用程序专用的数据。text/plain、text/html等等。
    2. Referer:发起请求的页面所在的地址;
    3. Accept-Charset:表示客户端能够接受的字符编码;
    4. Accept-Encoding:表示客户端希望服务端返回的内容编码;
    5. Accept-Language:表示客户端需要服务端返回的语言类型。
    6. User-Agent:对发起请求的客户端进行描述;
    7. Content-Type:当请求包含主体的时候,这个首部用于记录主体内容的类型;在发送POST或者PUT请求时,内容的类型默认为x-www-form-urlencoded,但是在上传文件时,内容的类型应该设置为multipart/form-data。
    8. Host:服务器域名
    9. Content-Length:请求主体的字节长度
    10. Connection:是否需要持久连接,在HTTP/1.1之后默认开启持久连接
    11. Cache-Control:对缓存进行控制
    12. Cookie: 通常用于告知服务端两个请求是否来自同一浏览器,也就是说让服务端识别客户端的身份,使得基于无状态的HTTP协议记录稳定的状态信息成为可能。一般是服务器为了辨别用户身份将特定的数据(Token)存储在用户本地终端上的数据。
    13. Authorization:用于向服务器发送基本的身份验证证书,服务器只有收到认证后才会返回给客户端200 OK响应,如果没有认证信息,则会返回401并告知客户端需要认证信息。
    14. 参考文档:https://cloud.tencent.com/developer/article/1586859
  3. 请求体:图总的报文体5,可以传递请求参数,请求的URL也可以传递请求参数,格式为"/chapter15/user.html?param1=value1&param2=value2";

HTTP响应:HTTP响应是针对客户端发来请求的回应,响应报文如下图所示,主要由三部分组成:状态行、响应头、响应正文。

  1. 状态行:即上述图片的第一行,由HTTP协议版本、状态码及描述组成。状态码参考浏览器输入URL到显示网页全过程
  2. 响应头:
    1. Server:返回响应的服务器的域名;
    2. Content-Type:服务器响应体的数据类型
    3. Location:仅在重定向的时候使用,会告诉客户端接下来应该向哪个URL发送请求;
    4. Set-Cookie 服务端可以设置客户端的Cookie
    5. Date:服务器发出响应报文的时间
    6. Last-Modified:请求资源的最后的修改时间
    7. Content-Length:响应主体的字节长度
    8. Content-Type:如果响应包含可选的主体,那么这个首部记录的就是主体内容的类型。
  3. 响应体:响应的具体数据

3.2 HTTP的四个版本

其他比较见:浏览器输入URL到显示网页全过程.md

  1. HTTP/0.9:仅支持GET请求方式,且不支持请求头;只支持纯文本一种内容,仅能请求访问HTML格式的资源里面不能插入图片。HTTP/0.9具有典型的无状态性,每个事务独立进行处理,事务结束时就释放这个连接。
  2. HTTP/1.0:
    1. 在0.9版本上做了改进,增加了POST、HEAD;
    2. Content-Type可以支持多种数据格式;
    3. 支持缓存;状态码;
    4. 内容编码,由于发送的数据可以是任何格式,因此可以把数据压缩后再发送;
    5. 但是1.0版本每次TCP连接只能发送一个请求,当服务器响应后就会关闭这次连接,下一个请求需要再次建立TCP连接, 解决方案用了一个非标准的Connection:keep-alive。
  3. HTTP/1.1:
    1. 最大变化就是加入了持久连接,即TCP连接默认不关闭,可以被多个HTTP请求复用,不用声明Connection:keep-alive;
    2. 加入管道机制,在同一个TCP连接里,允许多个请求同时发送,增加了并发性。例如管道机制则是允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求。
    3. 新增请求:PUT、PATHCH、DELETE。
    4. HTTP/1.1支持文件断点续传,HTTP/1.0每次传送文件都是从文件头开始的。
    5. 虽然1.1版本允许复用TCP连接,但是同一个TCP连接里面,所有的通信时按次序进行的。服务端是按队列顺序处理请求的,服务器只有处理完一个回应,才会进行下一个回应。假如前面的请求处理时间很长,后面就会有许多请求排队等着,这样就造成了“队头阻塞”的问题;同时HTTP是无状态的连接,因此每次请求都需要添加重复的字段,降低了带宽的利用率。
  4. HTTP/2.0:
    1. 多工模式:HTTP/2是完全多路复用的,即多个请求和响应可以在同一时间使用同一个连接,解决了队头阻塞的问题;
    2. HTTP2.0是一种二进制协议,不仅让HTTP/2的语法分析变得更快,还能够让协议变得更为紧凑和健壮;
    3. HTTP请求和响应中,状态行和请求/响应头都是些信息字段,并没有真正的数据,因此HTTP/2会对首部进行压缩以减少需要传送的数据量。
    4. 增加服务器推送的功能,即不经请求服务端主动向客户端发送数据。意思就是说,当我们对支持HTTP/2.0的web服务器请求数据的时候,服务器会顺便把一些客户端需要的资源一起推送到客户端,免得客户端再次创建连接发送请求到服务器端获取。这种方式适合静态资源加载。
  5. HTTP/3.0:
    1. HTTP3.0,也称作HTTP over QUIC,核心就是QUIC(读音quick)协议,由google在2015年提出的SPDYv3演化而来,传统的HTTP协议是基于传输层TCP的协议,而QUIC是基于传输层UDP上的协议,可以定义成:HTTP3.0基于UDP的安全可靠的HTTP2.0协议。
    2. 尽管HTTP/2解决了很多1.1的问题,但是HTTP/2仍然存在一些缺陷,这些缺陷来源于底层TCP协议,我们知道TCP连接是可靠的连接,如果出现了丢包,那么整个连接都要等待重传,HTTP/1.1可以同时使用6个TCP连接,一个阻塞其他五个还能工作,但是HTTP/2只有一个TCP连接,阻塞的问题便被放大了。
    3. 由于TCP协议被广泛使用,很难修改TCO协议,所以,HTTP/2在UDP的基础上实现多路复用、0-RTT、TLS加密、流量控制、丢包重传等功能。
    4. QUIC的实现机制:https://blog.csdn.net/weixin_35925956/article/details/114468125
      1. 自定义连接机制:
      2. 自定义重传机制:
      3. 无阻塞的多路复用:
      4. 自定义流量控制:
  6. 总结:
    1. HTTP/0.9:仅支持GET方法,只能发送HTML格式字符串;
    2. HTTP/1.0:支持多种数据格式,增加POST、HEAD等方法,增加头信息,每次只能传送一个请求;
    3. HTTP/1.1:加入持久连接,请求管道化、增加缓存处理、增加Host字段、支持断点续传分块传输等;
    4. HTTP/2.0:多路复用、二进制分帧、头部压缩、服务器推送。
    5. HTTP/3.0:基于UDP、多路复用、快速建立连接、加密认证、向前纠错机制。

3.3 长连接、短连接

  • 在HTTP/1.0中默认使用短连接,客户端和服务器每进行一次HTTP操作,就建立一次TCP连接,任务结束后就中断连接。操作步骤为:建立连接-传输数据-关闭连接...建立连接-传输数据-关闭连接;
  • 从HTTP/1.1起,默认使用长连接。客户端和服务器之间用于传输HTTP的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这条已经建立的连接。操作步骤为:建立连接-传输数据...保持连接...传输数据-关闭连接

3.4 HTTPS

SSL(Secure Socket Layer, 安全套接层):是基于HTTP下、TCP之上的一个协议加密层,是基于HTTP标准并对TCP传输数据时进行加密。TSL(Transport Layer Security,安全传输层协议)是对SSL标准化后的,添加了少数的机制。

  1. 由于HTTP是明文传输,所以存在着很大的安全隐患。HTTPS是基于HTTP的扩展,用于计算机网络的安全通信。在HTTPS中,原有的HTTP协议会得到TLS(安全传输层协议)或其前辈SSL(安全套接层)的加密,因此HTTPS也常指HTTP over TLS或HTTP over SSL。两者的关系如下:

  2. TLS握手是启动HTTPS通信的过程,类似于TCP建立连接时的三次握手。在TLS握手的过程中,通信双方交换消息以相互验证,相互确认,并确认它们所要使用的加密算法以及会话秘钥(用于对称加密的秘钥)。过程如下:

    1. client hello:客户端通过发送client hello消息向服务器发送握手请求,该消息包含了客户端所支持的TSL版本、支持的加密算法A、B、C等等以及一个随机字符串 client random。
    2. server hello:服务端发送 server hello 消息对客户端进行回应,该消息包含了服务器的数字证书CA、服务器选择的加密算法A和一个随机字符串 server random。
      1. 注:CA证书是需要申请并且由专门的数字证书认证机构通过非常严格的审核之后颁发的电子证书;
      2. 证书颁发的同时会生成一个公钥和一个私钥(非对称加密)。私钥由服务端自己保存,不可泄露;公钥则是存放在证书的信息中,可以公开。
      3. 证书本身也会带一个证书电子签名,这个签名用来验证证书的完整性和真实性,可以辨认证书是否被篡改。
    3. 验证:客户端对服务端发来的证书进行验证,确保对方的合法身份,验证过程主要包括检查数字签名、验证证书链、检查证书的有效期、检查证书的撤回状态(撤回代表证书已失效)。
    4. premaster secret:客户端生成一个随机字符串premaster secret,并使用服务端的公钥将其加密并发送给服务端(只有使用相应的私钥才能解密);
    5. 服务器使用私钥解密获取随机字符串premaster secret;
    6. 生成共享密钥:客户端和服务端均使用达成共识的加密算法A对client random、server random 和premaster secret生成一个密钥KEY。
    7. 客户端就绪:客户端发送经过共享密钥KEY加密过的finished信号;
    8. 服务器就绪:服务端发送经过共享密钥KEY加密过的finished信号;
    9. 达成安全通信:握手完成,双方使用对称加密进行安全通信,密钥为KEY。
    10. 参考链接:https://segmentfault.com/a/1190000021559557
  3. 与HTTP的区别:

    1. 最重要的区别就是安全性,HTTP明文传输,不对数据进行加密,安全性较差;HTTPS的数据传输过程是经过加密的,安全性较好;
    2. 使用HTTPS协议需要申请CA证书,一般免费的证书较少,需要一定的费用;
    3. HTTP页面的响应速度比HTTPS快,因为HTTPS加了一层安全层,建立连接的过程更加复杂,也要交换更多的数据;
    4. HTTPS是构建在SSL/TLS之上的协议,所以要比HTTP更耗费服务器资源;
    5. HTTP和HTTPS使用的是完全不同的连接方式,使用的端口也不一样,前者使用的是80,后者使用的是443.

3.5 get、post区别

HTTP的底层是TCP/IP,GET和POST是HTTP协议中的两种请求方式,所以GET和POST的底层也是TCP链接。本质上是一样的,所谓的区别只是浏览器、服务端之间的约定、限制而已。

  1. GET在浏览器回退时是无害的,而POST中的数据会被重新提交;
  2. GET产生的URL地址可以被收藏为书签,而POST不可以;
  3. GET请求会被浏览器主动缓存,而POST不会,除非手动设置;
  4. GET请求只能进行url编码application/x-www-form-urlencoded,而POST支持多种编码方式,例如application/x-www-form-urlencoded 或 multipart/form-data;
  5. GET请求的参数会被完整的保留在浏览器历史记录里,而POST中的参数不会被保留;
  6. GET请求在URL中传送的参数是有长度限制的,而POST没有;
    1. HTTP/1.1协议中对url的长度是不受限制的,但是在真正的实现中,url的长度还是受到限制的,一是服务器端的限制,二是浏览器端的限制。
  7. 对参数的数据类型,GET只接受ASCII字符,而POST没有限制;
  8. GET比POST更不安全,因为GET参数是直接通过URL参数,POST中的参数是放在Request Body中的,所以GET不能用来传递敏感信息;
  9. 最重要的一个区别是GET请求只会产生一个包,而POST会产生两个:
  10. 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200。
  11. 而对于POST,浏览器先发送header,收到服务器响应的100 continue,浏览器再发送data,服务器响应200。当然并不是所有浏览器POST都会发两次包,Firefox就只发一次。
  12. 参考链接:https://www.cnblogs.com/logsharing/p/8448446.html

3.6 安全性、幂等性

  1. 安全性:如果一个HTTP方法只要求服务器提供信息而不会对服务器的状态做任何修改,那么这个方法就是安全的。

    1. GET、HEAD、OPTION和TRACE都不会对服务器的状态进行修改,所以它们都是安全的方法;
    2. POST、PUT和DELETE都能够对服务器的状态进行修改(比如在处理POST请求时,服务器存储的数据就可能发生变化),所以这三个不是安全的方法。
  2. 幂等性:如果一个HTTP方法在使用相同的数据进行第二层调用的时候,不会对服务器的状态造成任何的改变,那么这个方法就是幂等的。也就是说执行任意多次与一次执行产生的影响相同。

    1. 根据安全的方法的定义,所有安全的方法都不会改变服务器的状态,所以它们天生就是幂等的;
    2. PUT和DELETE虽然不安全,但却是幂等的, 因为它们在进行第二次调用时都不会改变服务器的状态。执行完一个PUT请求之后,URI执行的资源已经被更新或者创建,当再次执行,服务器的状态也没有改变;DELETE用于删除数据,第二次执行时可能会返回一个错误状态,但是服务器的状态也没有改变。
    3. 重复的POST请求是否会改变服务器状态是由服务器自身决定的,所以POST方法既不安全也不幂等。

4、DHCP

动态主机配置协议DHCP(Dynamic Host Configuration Protocol),它提供了一种机制,称为即插即用连网,这种机制允许一台计算机加入新的网络和获取IP地址而不用手工参与。
工作原理:

  1. 需要IP地址的主机在启动时就向DHCP服务器广播发送发现报文(DHCP DISCOVER)(将目的IP地址置为全1,即255.255.255.255),这时该主机就成为DHCP客户;发送广播报文是因为现在还不知道DHCP服务器在什么地方,因此要发现DHCP服务器的IP地址,同时这台主机目前还没有自己的IP地址,因此它将IP数据报的源IP地址设为全0。
  2. 本地网络上的所有主机都能够收到这个广播报文,但只有DHCP服务器才会对此广播报文进行回答。DHCP服务器会先在其数据库中查找该计算机的配置信息,若找到直接返回;否则从服务器的IP地址池中取一个地址分配给该计算机。
posted @ 2021-06-20 10:22  xiaofeidu  阅读(402)  评论(0编辑  收藏  举报