分类目录归档:网络编程

网络协议基础

网络协议基础

1. TCP和UDP有什么区别

TCP与UDP区别总结:

1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接.
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付.
3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的.
UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等).
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信.
5、TCP首部开销20字节;UDP的首部开销小,只有8个字节.
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道.

因此UDP不提供复杂的控制机制,利用IP提供面向无连接的通信服务,随时都可以发送数据,处理简单且高效.

UDP经常用于以下场景:

  • 包总量较小的通信(DNS、SNMP)

  • 视频、音频等多媒体通信(即时通信)

  • 广播通信

TCP 使用场景:

相对于 UDP,TCP 实现了数据传输过程中的各种控制,可以进行丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。

在对可靠性要求较高的情况下,可以使用 TCP,即不考虑 UDP 的时候,都可以选择 TCP。

2. TCP中三次握手和四次挥手

  • 三次握手

假设 A 为客户端,B 为服务器端。

  • 首先 B 处于 LISTEN(监听)状态,等待客户的连接请求。
  • A 向 B 发送连接请求报文段,SYN=1ACK=0,选择一个初始的序号 seq = x
  • B 收到连接请求报文段,如果同意建立连接,则向 A 发送连接确认报文段,SYN=1ACK=1,确认号为 x+1,同时也选择一个初始的序号 seq = y
  • A 收到 B 的连接确认报文段后,还要向 B 发出确认,确认号为 ack = y+1,序号为 seq = x+1
  • A 的 TCP 通知上层应用进程,连接已经建立。
  • B 收到 A 的确认后,连接建立。
  • B 的 TCP 收到主机 A 的确认后,也通知其上层应用进程:TCP 连接已经建立。

为什么TCP连接需要三次握手,两次不可以吗,为什么?

TCP是一个双向通信协议,通信双方都有能力发送信息,并接收响应。如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认

  • 四次挥手

数据传输结束后,通信的双方都可释放连接。现在 A 的应用进程先向其 TCP 发出连接释放报文段,并停止再发送数据,主动关闭 TCP连接。

  • A 把连接释放报文段首部的 FIN = 1,其序号 seq = u,等待 B 的确认。
  • B 发出确认,确认号 ack = u+1,而这个报文段自己的序号 seq = v。(TCP 服务器进程通知高层应用进程)。
  • 从 A 到 B 这个方向的连接就释放了,TCP 连接处于半关闭状态。A 不能向 B 发送数据;B 若发送数据,A 仍要接收。
  • 当 B 不再需要连接时,发送连接释放请求报文段,FIN=1。
  • A 收到后发出确认,进入TIME-WAIT状态,等待 2 MSL(2*2 = 4 mins)时间后释放连接。
  • B 收到 A 的确认后释放连接。

四次挥手的原因:

客户端发送了 FIN 连接释放报文之后,服务器收到了这个报文,

3. TCP的LISTEN状态是什么

TCP的LISTEN是服务器处于监听状态:

  • CLOSED:初始状态。
  • LISTEN:服务器处于监听状态。
  • TIME_WAIT:客户端收到服务端的FIN包,并立即发出ACK包做最后的确认,在此之后的2MSL时间称为TIME_WAIT状态。

4. 常见的HTTP状态码有哪些

5. 301和302有什么区别

301: Moved Permanently 被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。

302 Found 请求的资源现在临时从不同的URI响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。

301是永久重定向,而302是临时重定向。

6. 504和500有什么区别

500的错误通常是由于服务器上代码出错或者是抛出了异常.

502即 Bad Gateway网关(这里的网关是指CGI,即通用网关接口)错误,通常是程序空指针错误。

504即Gateway timeout,即超时错误.

7. HTTPS和HTTP有什么区别

http协议和https协议的区别:传输信息安全性不同、连接方式不同、端口不同、证书专申请方式不同.

一、传输信息安全性不同

  1. http协议:是超文本传输协议,信息是明文传输。如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息。

  2. https协议:是具有安全性的ssl加密传输协议,为浏览器和服务器之间的通信加密,确保数据传输的安

二,连接方式不同

  1. http协议:http的连接很简单,是无状态的。
  2. https协议:是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议。

三、端口不同

  1. http协议:使用的端口是80。
  2. https协议:使用的端口是443.

四、证书申请方式不同

  1. http协议:免费申请。

  2. https协议:需要到ca申请证书,一般免费证书很少,需要交费。

3. Quic有什么优点相比Http2

  • HTTP1 有连接无法复用、队头阻塞、协议开销大和安全因素等多个缺陷.
  • HTTP2通过多路复用、二进制流、Header 压缩等等技术,极大地提高了性能,但是还是存在着问题的
  • Quic 基于 UDP 实现,是 HTTP3 中的底层支撑协议,该协议基于 UDP,又取了 TCP 中的精华,实现了即快又可靠的协议.quic中加密认证的报文,(TCP 协议头部没有经过任何加密和认证,所以在传输过程中很容易被中间网络设备篡改,注入和窃听。比如修改序列号、滑动窗口。这些行为有可能是出于性能优化,也有可能是主动攻击。)这样只要对 QUIC 报文任何修改,接收端都能够及时发现,有效地降低了安全风险。

此外quic还有向前纠错的能力,QUIC 协议有一个非常独特的特性,称为向前纠错 (Forward Error Correction,FEC),每个数据包除了它本身的内容之外,还包括了部分其他数据包的数据,因此少量的丢包可以通过其他包的冗余数据直接组装而无需重传。

向前纠错牺牲了每个数据包可以发送数据的上限,但是减少了因为丢包导致的数据重传,因为数据重传将会消耗更多的时间(包括确认数据包丢失、请求重传、等待新数据包等步骤的时间消耗),

假如说这次我要发送三个包,那么协议会算出这三个包的异或值并单独发出一个校验包,也就是总共发出了四个包。当出现其中的非校验包丢包的情况时,可以通过另外三个包计算出丢失的数据包的内容。
当然这种技术只能使用在丢失一个包的情况下,如果出现丢失多个包就不能使用纠错机制了,只能使用重传的方式了。

Quic 相比现在广泛应用的 http2+tcp+tls 协议有如下优势:

减少了 TCP 三次握手及 TLS 握手时间。改进的拥塞控制。避免队头阻塞的多路复用。连接迁移。前向冗余纠错.

9. Grpc的优缺点

gRPC是Google公司基于Protobuf开发的跨语言的开源RPC框架。gRPC基于HTTP/2协议设计,可以基于一个HTTP/2链接提供多个服务,对于移动设备更加友好。

最底层为TCP或Unix Socket协议,在此之上是HTTP/2协议的实现,然后在HTTP/2协议之上又构建了针对Go语言的gRPC核心库。应用程序通过gRPC插件生产的Stub代码和gRPC核心库通信,也可以直接和gRPC核心库通信。

Grpc优缺点:

优点:

  • protobuf二进制消息,性能好/效率高(空间和时间效率都很不错)
  • proto文件生成目标代码,简单易用
  • 序列化反序列化直接对应程序中的数据类,不需要解析后在进行映射(XML,JSON都是这种方式)
  • 支持向前兼容(新加字段采用默认值)和向后兼容(忽略新加字段),简化升级
  • 支持多种语言(可以把proto文件看做IDL文件)

缺点:

  • GRPC尚未提供连接池,需要自行实现
  • 尚未提供“服务发现”、“负载均衡”机制
  • 因为基于HTTP2,绝大部多数HTTP Server、Nginx都尚不支持,即Nginx不能将GRPC请求作为HTTP请求来负载均衡,而是作为普通的TCP请求。(nginx1.9版本已支持)
  • Protobuf二进制可读性差(貌似提供了Text_Fromat功能)默认不具备动态特性(可以通过动态定义生成消息类型或者动态编译支持)

10. Get和Post区别

Get和Post的区别和不同:

  1. Get是不安全的,因为在传输过程,数据被放在请求的URL中;Post的所有操作对用户来说都是不可见的。

  2. Get传送的数据量较小,这主要是因为受URL长度限制;Post传送的数据量较大,一般被默认为不受限制。

  3. Get限制Form表单的数据集的值必须为ASCII字符;而Post支持整个ISO10646字符集。

  4. Get执行效率却比Post方法好。Get是form提交的默认方法。

  5. GET产生一个TCP数据包;POST产生两个TCP数据包。(非必然,客户端可灵活决定)

6. Unicode和ASCII以及Utf8的区别

计算机内部,所有信息最终都是一个二进制值。每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。

也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从00000000到11111111。

上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为 ASCII 码,一直沿用至今。

ASCII 码一共规定了128个字符的编码,比如空格SPACE是32(二进制00100000),大写的字母A是65(二进制01000001)。

这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的一位统一规定为0。

  • Unicode 是字符集
    如果有一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是 Unicode,就像它的名字都表示的,这是一种所有符号的编码。
    Unicode 当然是一个很大的集合,现在的规模可以容纳100多万个符号。

  • UTF-8 是编码规则

Unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。

互联网的普及,强烈要求出现一种统一的编码方式。UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式。其他实现方式还包括 UTF-16(字符用两个字节或四个字节表示)和 UTF-32(字符用四个字节表示),不过在互联网上基本不用。
这里需要注意下,这里的关系是,UTF-8 是 Unicode 的实现方式之一。

12. Cookie与Session异同

Cookie 和 Session 都为了用来保存状态信息,都是保存客户端状态的机制,它们都是为了解决HTTP无状态的问题而所做的努力。

  • Cookie机制

简单地说,Cookie 就是浏览器储存在用户电脑上的一小段文本文件。Cookie 是纯文本格式,不包含任何可执行的代码。
一个 Web 页面或服务器告知浏览器按照一定规范来储存这些信息,并在随后的请求中将这些信息发送至服务器,Web 服务器就可以使用这些信息来识别不同的用户。
大多数需要登录的网站在用户验证成功之后都会设置一个 Cookie,只要这个 Cookie 存在并可以,用户就可以自由浏览这个网站的任意页面。

Cookie 会被浏览器自动删除,通常存在以下几种原因:

  1. 会话 Cooke (Session Cookie) 在会话结束时(浏览器关闭)会被删除
  2. 持久化 Cookie(Persistent Cookie)在到达失效日期时会被删除
  3. 如果浏览器中的 Cookie 数量达到限制,那么 Cookie 会被删除以为新建的 Cookie 创建空间。

大多数浏览器支持最大为 4096 字节的 Cookie。由于这限制了 Cookie 的大小,最好用 Cookie 来存储少量数据,或者存储用户 ID 之类的标识符。

用户 ID 随后便可用于标识用户,以及从数据库或其他数据源中读取用户信息。 浏览器还限制站点可以在用户计算机上存储的 Cookie 的数量。

大多数浏览器只允许每个站点存储 20 个 Cookie;如果试图存储更多 Cookie,则最旧的 Cookie 便会被丢弃。

有些浏览器还会对它们将接受的来自所有站点的 Cookie 总数作出绝对限制,通常为 300 个。

使用 Cookie 的缺点:

  1. 不良站点用 Cookie 收集用户隐私信息;

  2. Cookie窃取:黑客以可以通过窃取用户的cookie来模拟用户的请求行为。(跨站脚本攻击XSS)

  3. Session 机制

Session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个Session标识(Session id).

如果已包含一个SessionID 则说明以前已经为此客户端创建过Session,服务器就按照SessionID把这个 Session检索出来使用(如果检索不到,可能会新建一个)。
如果客户端请求不包含SessionID,则为此客户端创建一个Session并且生成一个与此Session相关联的SessionID,SessionID的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个SessionID将被在本次响应中返回给客户端保存。

具体实现方式:

  • Cookie方式

服务器给每个Session分配一个唯一的JSESSIONID,并通过Cookie发送给客户端。

当客户端发起新的请求的时候,将在Cookie头中携带这个JSESSIONID,这样服务器能够找到这个客户端对应的Session。

  • URL回写

服务器在发送给浏览器页面的所有链接中都携带JSESSIONID的参数,这样客户端点击任何一个链接都会把JSESSIONID带回服务器。如果直接在浏览器输入服务端资源的url来请求该资源,那么Session是匹配不到的。

Web 缓存:

WEB缓存(cache)位于Web服务器和客户端之间,缓存机制会根据请求保存输出内容的副本,例如html页面,图片,文件,当下一个请求来到的时候:如果是相同的URL,缓存直接使用副本响应访问请求,而不是向源服务器再次发送请求。

主要分三种情况:

  1. 未找到缓存(黑色线):当没有找到缓存时,说明本地并没有这些数据,这种情况一般发生在我们首次访问网站,或者以前访问过,但是清除过缓存后。

浏览器就会先访问服务器,然后把服务器上的内容取回来,内容取回来以后,就要根据情况来决定是否要保留到缓存中了。

  1. 缓存未过期(蓝色线):缓存未过期,指的是本地缓存没有过期,不需要访问服务器了,直接就可以拿本地的缓存作为响应在本地使用了。这样节省了不少网络成本,提高了用户体验过。

  2. 缓存已过期(红色线):当满足过期的条件时,会向服务器发送请求,发送的请求一般都会进行一个验证,目的是虽然缓存文档过期了,但是文档内容不一定会有什么改变,所以服务器返回的也许是一个新的文档,这时候的HTTP状态码是200,或者返回的只是一个最新的时间戳和304状态码。

缓存过期后,有两种方法来判定服务端的文件有没有更新。

第一种在上一次服务端告诉客户端约定的有效期的同时,告诉客户端该文件最后修改的时间,当再次试图从服务端下载该文件的时候,check下该文件有没有更新(对比最后修改时间),如果没有,则读取缓存.

第二种方式是在上一次服务端告诉客户端约定有效期的同时,同时告诉客户端该文件的版本号,当服务端文件更新的时候,改变版本号,再次发送请求的时候check一下版本号是否一致就行了,如一致,则可直接读取缓存。

浏览器是依靠请求和响应中的的头信息来控制缓存的,如下:

  • Expires与Cache-Control:服务端用来约定和客户端的有效时间的。

Expires规定了缓存失效时间(Date为当前时间),而Cache-Control的max-age规定了缓存有效时间(2552s)。

Expires是HTTP1.0的东西,而Cache-Control是HTTP1.1的,规定如果max-age和Expires同时存在,前者优先级高于后者。

  • Last-Modified/If-Modified-Since缓存过期后,check服务端文件是否更新的第一种方式。

  • ETag/If-None-Match:缓存过期时check服务端文件是否更新的第二种方式。

实际上ETag并不是文件的版本号,而是一串可以代表该文件唯一的字符串,当客户端发现和服务器约定的直接读取缓存的时间过了,就在请求中发送If-None-Match选项,值即为上次请求后响应头的ETag值.
该值在服务端和服务端代表该文件唯一的字符串对比(如果服务端该文件改变了,该值就会变),如果相同,则相应HTTP304,客户端直接读取缓存,如果不相同,HTTP200,下载正确的数据,更新ETag值。

当然并不是所有请求都能被缓存。无法被浏览器缓存的请求:

  1. HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache(HTTP1.0),或Cache-Control:max-age=0等告诉浏览器不用缓存的请求
  2. 需要根据Cookie,认证信息等决定输入内容的动态请求是不能被缓存的
  3. POST请求无法被缓存

浏览器缓存过程还和用户行为有关。譬如先打开一个主页有个jquery的请求(假设访问后会缓存下来)。

接着如果直接在地址栏输入 jquery 地址,然后回车,响应HTTP200(from cache),因为有效期还没过直接读取的缓存;如果ctrl+r进行刷新,则会相应HTTP304(Not Modified),虽然还是读取的本地缓存,但是多了一次服务端的请求;而如果是ctrl+shift+r强刷,则会直接从服务器下载新的文件,响应HTTP200。

13. Client如何实现长连接

TCP协议的KeepAlive机制与HeartBeat心跳包

  • HeartBeat心跳包

很多应用层协议都有HeartBeat机制,通常是客户端每隔一小段时间向服务器发送一个数据包,通知服务器自己仍然在线,并传输一些可能必要的数据。使用心跳包的典型协议是IM,比如QQ/MSN/飞信等协议。

心跳包之所以叫心跳包是因为:它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着。事实上这是为了保持长连接,至于这个包的内容,是没有什么特别规定的,不过一般都是很小的包,或者只包含包头的一个空包。

在TCP的机制里面,本身是存在有心跳包的机制的,也就是TCP的选项:SO_KEEPALIVE。系统默认是设置的2小时的心跳频率。但是它检查不到机器断电、网线拔出、防火墙这些断线。而且逻辑层处理断线可能也不是那么好处理。一般,如果只是用于保活还是可以的。

心跳包一般来说都是在逻辑层发送空的echo包来实现的。下一个定时器,在一定时间间隔下发送一个空包给客户端,然后客户端反馈一个同样的空包回来,服务器如果在一定时间内收不到客户端发送过来的反馈包,那就只有认定说掉线了。

其实,要判定掉线,只需要send或者recv一下,如果结果为零,则为掉线。但是,在长连接下,有可能很长一段时间都没有数据往来。

理论上说,这个连接是一直保持连接的,但是实际情况中,如果中间节点出现什么故障是难以知道的。更要命的是,有的节点(防火墙)会自动把一定时间之内没有数据交互的连接给断掉。在这个时候,就需要我们的心跳包了,用于维持长连接,保活。

在获知了断线之后,服务器逻辑可能需要做一些事情,比如断线后的数据清理呀,重新连接呀……当然,这个自然是要由逻辑层根据需求去做了。

总的来说,心跳包主要也就是用于长连接的保活和断线处理。一般的应用下,判定时间在30-40秒比较不错。如果实在要求高,那就在6-9秒。

  • TCP协议的KeepAlive机制

TCP的IP传输层的两个主要协议是UDP和TCP,其中UDP是无连接的、面向packet的,而TCP协议是有连接、面向流的协议。

TCP的KeepAlive机制,首先它貌似默认是不打开的,要用setsockoptSOL_SOCKET.SO_KEEPALIVE设置为1才是打开,并且可以设置三个参数tcp_keepalive_time/tcp_keepalive_probes/tcp_keepalive_intvl,分别表示连接闲置多久开始发keepalive的ack包、发几个ack包不回复才当对方死了、两个ack包之间间隔多.

在测试的时候用Ubuntu Server 10.04下面默认值是7200秒(2个小时,要不要这么蛋疼啊!)、9次、75秒。

于是连接就了有一个超时时间窗口,如果连接之间没有通信,这个时间窗口会逐渐减小,当它减小到零的时候,TCP协议会向对方发一个带有ACK标志的空数据包(KeepAlive探针),对方在收到ACK包以后,如果连接一切正常,应该回复一个ACK;如果连接出现错误了(例如对方重启了,连接状态丢失),则应当回复一个RST;如果对方没有回复,服务器每隔intvl的时间再发ACK,如果连续probes个包都被无视了,说明连接被断开了。

在http早期,每个http请求都要求打开一个tpc socket连接,并且使用一次之后就断开这个tcp连接。

使用keep-alive可以改善这种状态,即在一次TCP连接中可以持续发送多份数据而不会断开连接。通过使用keep-alive机制,可以减少tcp连接建立次数,也意味着可以减少TIME_WAIT状态连接,以此提高性能和提高httpd服务器的吞吐率(更少的tcp连接意味着更少的系统内核调用,socket的accept()close()调用)。

但是,keep-alive并不是免费的午餐,长时间的tcp连接容易导致系统资源无效占用。配置不当的keep-alive,有时比重复利用连接带来的损失还更大。所以,正确地设置keep-alive timeout时间非常重要。

使用http keep-alvie,可以减少服务端TIME_WAIT数量(因为由服务端httpd守护进程主动关闭连接)。道理很简单,相较而言,启用keep-alive,建立的tcp连接更少了,自然要被关闭的tcp连接也相应更少了。

使用启用keepalive的不同。另外,http keepalive是客户端浏览器与服务端httpd守护进程协作的结果,所以,我们另外安排篇幅介绍不同浏览器的各种情况对keep-alive的利用。

14. Http1和Http2和Grpc之间的区别是什么

在互联网流量传输只使用了几个网络协议。使用 IPv4 进行路由,使用 TCP 进行连接层面的流量控制,使用 SSL/TLS 协议实现传输安全,使用 DNS 进行域名解析,使用 HTTP 进行应用数据的传输。

但是使用Http进行应用数据的传输,却是在不断的改变,那么Http1和Http2和Grpc之间的区别是什么,我们下面分析下.

通常影响一个 HTTP 网络请求的因素主要有两个:带宽和延迟。

  • 带宽

如果说我们还停留在拨号上网的阶段,带宽可能会成为一个比较严重影响请求的问题,但是现在网络基础建设已经使得带宽得到极大的提升,我们不再会担心由带宽而影响网速,那么就只剩下延迟了。

  • 延迟

浏览器阻塞(HOL blocking):浏览器会因为一些原因阻塞请求。浏览器对于同一个域名,同时只能有 4 个连接(这个根据浏览器内核不同可能会有所差异),超过浏览器最大连接数限制,后续请求就会被阻塞。

DNS 查询(DNS Lookup):浏览器需要知道目标服务器的 IP 才能建立连接。将域名解析为 IP 的这个系统就是 DNS。这个通常可以利用DNS缓存结果来达到减少这个时间的目的。

建立连接(Initial connection):HTTP 是基于 TCP 协议的,浏览器最快也要在第三次握手时才能捎带 HTTP 请求报文,达到真正的建立连接,但是这些连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对文件类大请求影响较大。

然而,HTTP2并不是对HTTP1协议的重写,相对于HTTP1,HTTP2 的侧重点主要在性能。其中请求方法,状态码和语义和HTTP1都是相同的,可以使用与 HTTP1相同的 API(可能有一些小的添加)来表示协议。

HTTP2主要有两个规范组成:

  • Hypertext Transfer Protocol version 2 (超文本传输协议版本 2)
  • HPACK - HTTP2 的头压缩 (HPACK 是一种头部压缩算法)

HTTP2和HTTP1相比的新特性包括:

  • 新的二进制格式(Binary Format)

HTTP1.x的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。

  • 多路复用(MultiPlexing)

连接共享,即每一个request都是是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。

  • Header压缩

Header压缩,如上文中所言,对前面提到过HTTP1.x的header带有大量信息,而且每次都要重复发送,HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。

  • 服务端推送(server push)

服务端推送(server push),同SPDY一样,HTTP2.0也具有server push功能。

Grpc的设计目标是在任何环境下运行,支持可插拔的负载均衡,跟踪,运行状况检查和身份验证。它不仅支持数据中心内部和跨数据中心的服务调用,它也适用于分布式计算的最后一公里,将设备,移动应用程序和浏览器连接到后端服务,同时,它也是高性能的,而 HTTP2 恰好支持这些。

而Grpc是基于http2的.

  • HTTP2天然的通用性满足各种设备,场景.
  • HTTP2的性能相对来说也是很好的,除非你需要极致的性能.
  • HTTP2的安全性非常好,天然支持 SSL.
  • HTTP2的鉴权也非常成熟.
  • Grpc基于 HTTP2 多语言实现也更容易.

15. Tcp中的拆包和粘包是怎么回事

拆包和粘包是在socket编程中经常出现的情况,在socket通讯过程中,如果通讯的一端一次性连续发送多条数据包,tcp协议会将多个数据包打包成一个tcp报文发送出去,这就是所谓的粘包。

而如果通讯的一端发送的数据包超过一次tcp报文所能传输的最大值时,就会将一个数据包拆成多个最大tcp长度的tcp报文分开传输,这就叫做拆包。

MTU:

泛指通讯协议中的最大传输单元。一般用来说明TCP/IP四层协议中数据链路层的最大传输单元,不同类型的网络MTU也会不同,我们普遍使用的以太网的MTU是1500,即最大只能传输1500字节的数据帧。可以通过ifconfig命令查看电脑各个网卡的MTU。

MSS:

指TCP建立连接后双方约定的可传输的最大TCP报文长度,是TCP用来限制应用层可发送的最大字节数。如果底层的MTU是1500byte,则 MSS = 1500- 20(IP Header) -20 (TCP Header) = 1460 byte。

16. TFO的原理是什么

TCP快速打开(TCP Fast Open,TFO)是对TCP的一种简化握手手续的拓展,用于提高两端点间连接的打开速度。
简而言之,就是在TCP的三次握手过程中传输实际有用的数据。这个扩展最初在Linux系统实现,Linux服务器,Linux系统上的Chrome浏览器,或运行在Linux上的其他支持的软件。
它通过握手开始时的SYN包中的TFO cookie来验证一个之前连接过的客户端。如果验证成功,它可以在三次握手最终的ACK包收到之前就开始发送数据,这样便跳过了一个绕路的行为,更在传输开始时就降低了延迟。
这个加密的Cookie被存储在客户端,在一开始的连接时被设定好。然后每当客户端连接时,这个Cookie被重复返回。

请求Tcp Fast Open Cookie

  • 客户端发送SYN数据包,该数据包包含Fast Open选项,且该选项的Cookie为空,这表明客户端请求Fast Open Cookie;
  • 支持TCP Fast Open的服务器生成Cookie,并将其置于SYN-ACK数据包中的Fast Open选项以发回客户端;
  • 客户端收到SYN-ACK后,缓存Fast Open选项中的Cookie。

17. TIME_WAIT的作用

主动关闭的Socket端会进入TIME_WAIT状态,并且持续2MSL时间长度,MSL就是maximum segment lifetime(最大分节生命期),这是一个IP数据包能在互联网上生存的最长时间,超过这个时间将在网络中消失。MSL在RFC 1122上建议是2分钟,而源自berkeley的TCP实现传统上使用30秒,因而,TIME_WAIT状态一般维持在1-4分钟。

  • 可靠地实现TCP全双工连接的终止

在进行关闭连接四路握手协议时,最后的ACK是由主动关闭端发出的,如果这个最终的ACK丢失,服务器将重发最终的FIN,因此客户端必须维护状态信息允 许它重发最终的ACK。

如果不维持这个状态信息,那么客户端将响应RST分节,服务器将此分节解释成一个错误(在java中会抛出connection reset的SocketException)。

因而,要实现TCP全双工连接的正常终止,必须处理终止序列四个分节中任何一个分节的丢失情况,主动关闭 的客户端必须维持状态信息进入TIME_WAIT状态。

  • 允许老的重复分节在网络中消逝

TCP分节可能由于路由器异常而“迷途”,在迷途期间,TCP发送端可能因确认超时而重发这个分节,迷途的分节在路由器修复后也会被送到最终目的地,这个 原来的迷途分节就称为lost duplicate。

在关闭一个TCP连接后,马上又重新建立起一个相同的IP地址和端口之间的TCP连接,后一个连接被称为前一个连接的化身 (incarnation),那么有可能出现这种情况,前一个连接的迷途重复分组在前一个连接终止后出现,从而被误解成从属于新的化身。

为了避免这个情况,TCP不允许处于TIME_WAIT状态的连接启动一个新的化身,因为TIME_WAIT状态持续2MSL,就可以保证当成功建立一个TCP连接的时 候,来自连接先前化身的重复分组已经在网络中消逝。

18. 网络的性能指标有哪些

通常是以4个指标来衡量网络的性能,分别是带宽、延时、吞吐率、PPS(Packet Per Second),它们表示的意义如下:

  • 带宽,表示链路的最大传输速率,单位是 b/s (比特 / 秒),带宽越大,其传输能力就越强。

  • 延时,表示请求数据包发送后,收到对端响应,所需要的时间延迟。不同的场景有着不同的含义,比如可以表示建立 TCP 连接所需的时间延迟,或一个数据包往返所需的时间延迟。

  • 吞吐率,表示单位时间内成功传输的数据量,单位是 b/s(比特 / 秒)或者 B/s(字节 / 秒),吞吐受带宽限制,带宽越大,吞吐率的上限才可能越高。

  • PPS,全称是 Packet Per Second(包 / 秒),表示以网络包为单位的传输速率,一般用来评估系统对于网络的转发能力。

当然,除了以上这四种基本的指标,还有一些其他常用的性能指标,比如:

  • 网络的可用性,表示网络能否正常通信;

  • 并发连接数,表示 TCP 连接数量;

  • 丢包率,表示所丢失数据包数量占所发送数据组的比率;

  • 重传率,表示重传网络包的比例;

计算机网络基础知识

计算机网络基础知识

计算机网络基础知识,主要围绕网络层、传输层、应用层,核心为 TCP 和 HTTP 两部分。

第一部分:传输层

1. OSI七层模型 TCP/IP四层模型 ,五层协议.

(1)五层协议

  • 应用层 :提供用户接口,特指能够发起网络流量的程序,比如客户端程序:QQ,MSN,浏览器等;服务器程序:web服务器,邮件服务器,流媒体服务器等等。数据单位为报文。
  • 运输层 :提供的是进程间的通用数据传输服务。由于应用层协议很多,定义通用的运输层协议就可以支持不断增多的应用层协议。运输层包括两种协议:
    • 传输控制协议 TCP,提供面向连接、可靠的数据传输服务,数据单位为报文段;
    • 用户数据报协议 UDP,提供无连接、尽最大努力的数据传输服务,数据单位为用户数据报。
    • TCP 主要提供完整性服务,UDP 主要提供及时性服务。
  • 网络层 :为主机间提供数据传输服务,而运输层协议是为主机中的进程提供服务。网络层把运输层传递下来的报文段或者用户数据报封装成分组。(负责选择最佳路径 规划IP地址)
    • 路由器查看数据包目标IP地址,根据路由表为数据包选择路径。路由表中的类目可以人工添加(静态路由)也可以动态生成(动态路由)。
  • 数据链路层 :不同的网络类型,发送数据的机制不同,数据链路层就是将数据包封装成能够在不同的网络传输的帧。能够进行差错检验,但不纠错,监测处错误丢掉该帧。
    • 帧的开始和结束,透明传输,差错校验
  • 物理层 :物理层解决如何在连接各种计算机的传输媒体上传输数据比特流,而不是指具体的传输媒体。物理层的主要任务描述为:确定与传输媒体的接口的一些特性,即:
    • 机械特性:例接口形状,大小,引线数目.
    • 电气特性:例规定电压范围 ( -5V 到 +5V )
    • 功能特性:例规定 -5V 表示 0,+5V 表示 1.
    • 过程特性:也称规程特性,规定建立连接时各个相关部件的工作步骤.

(2) ISO七层模型中表示层和会话层功能是什么?

  • 表示层 :数据压缩、加密以及数据描述。这使得应用程序不必担心在各台主机中表示/存储的内部格式(二进制、ASCII,比如乱码)不同的问题。

  • 会话层 :建立会话,如session认证、断点续传。通信的应用程序之间建立、维护和释放面向用户的连接。通信的应用程序之间建立会话,需要传输层建立1个或多个连接。(…后台运行的木马,netstat -n)

  • 说明:五层协议没有表示层和会话层,而是将这些功能留给应用程序开发者处理。

(3)数据在各层之间的传递过程

在向下的过程中,需要添加下层协议所需要的首部或者尾部,而在向上的过程中不断拆开首部和尾部。

  1. 路由器只有下面三层协议(三层是路由表,网络的本质其实就是路由),因为路由器位于网络核心中,不需要为进程或者应用程序提供服务,因此也就不需要运输层和应用层。
  2. 交换机只有下面两层协议(局域网就是两层协议通信,两层是转发表).

(4)TCP/IP四层模型

它只有四层,相当于五层协议中数据链路层和物理层合并为网络接口层

现在的 TCP/IP 体系结构不严格遵循 OSI 分层概念,应用层可能会直接使用 IP 层或者网络接口层。

TCP/IP 协议族是一种沙漏形状,中间小两边大,IP 协议在其中占用举足轻重的地位。

2. TCP报头格式和UDP报头格式

网络层只把分组发送到目的主机,但是真正通信的并不是主机而是主机中的进程。运输层提供了进程间的逻辑通信,运输层向高层用户屏蔽了下面网络层的核心细节,使应用程序看起来像是在两个运输层实体之间有一条端到端的逻辑通信信道。

(1)UDP 和 TCP 的特点

  • 用户数据报协议 UDP(User Datagram Protocol)是无连接的,尽最大可能交付,没有拥塞控制,面向报文(对于应用程序传下来的报文不合并也不拆分,只是添加 UDP 首部),支持一对一、一对多、多对一和多对多的交互通信。例如:视频传输、实时通信。

  • 传输控制协议 TCP(Transmission Control Protocol)是面向连接的,提供可靠交付,有流量控制,拥塞控制,提供全双工通信,面向字节流(把应用层传下来的报文看成字节流,把字节流组织成大小不等的数据块),每一条 TCP 连接只能是点对点的(一对一)。

(2)UDP 首部格式

首部字段只有 8 个字节,包括源端口、目的端口、长度、检验和。12 字节的伪首部是为了计算检验和临时添加的。

(3)TCP 首部格式


序号 seq :用于对字节流进行编号,例如序号为 301,表示第一个字节的编号为 301,如果携带的数据长度为 100 字节,那么下一个报文段的序号应为 401。[301,400]为序号301的数据长度,下一个则为401。
确认号 ack :期望收到的下一个报文段的序号。例如 B 正确收到 A 发送来的一个报文段,序号为 501,携带的数据长度为 200 字节,因此 B 期望下一个报文段的序号为 701,B 发送给 A 的确认报文段中确认号就为 701。
数据偏移 :指的是数据部分距离报文段起始处的偏移量,实际上指的是首部的长度。
确认 ACK :当 ACK=1 时确认号字段有效,否则无效。TCP 规定,在连接建立后所有传送的报文段都必须把 ACK 置 1。
同步 SYN :在连接建立时用来同步序号。当 SYN=1,ACK=0 时表示这是一个连接请求报文段。若对方同意建立连接,则响应报文中 SYN=1,ACK=1。
终止 FIN :用来释放一个连接,当 FIN=1 时,表示此报文段的发送方的数据已发送完毕,并要求释放连接。
窗口 :窗口值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。

3. TCP三次握手?那四次挥手呢?如何保障可靠传输

(1)三次握手

假设 A 为客户端,B 为服务器端。

  • 首先 B 处于 LISTEN(监听)状态,等待客户的连接请求。
  • A 向 B 发送连接请求报文段,SYN=1,ACK=0,选择一个初始的序号 seq = x。
  • B 收到连接请求报文段,如果同意建立连接,则向 A 发送连接确认报文段,SYN=1,ACK=1,确认号为 x+1,同时也选择一个初始的序号 seq = y
  • A 收到 B 的连接确认报文段后,还要向 B 发出确认,确认号为 ack = y+1,序号为 seq = x+1
  • A 的 TCP 通知上层应用进程,连接已经建立。
  • B 收到 A 的确认后,连接建立。
  • B 的 TCP 收到主机 A 的确认后,也通知其上层应用进程:TCP 连接已经建立。

(2)为什么TCP连接需要三次握手,两次不可以吗,为什么

为了防止已失效的连接请求报文段突然又传送到了服务端,占用服务器资源。(假设主机A为客户端,主机B为服务器端)

现假定出现一种异常情况,即A发出的第一个连接请求报文段并没有丢失,而是在某些网络节点长时间滞留了,以致延误到连接释放以后的某个时间才到B。本来这是一个已失效的报文段。但是B收到此失效的连接请求报文段后,就误认为是A有发出一次新的连接请求。于是就向A发出确认报文段,同意建立连接。假定不采用三次握手,那么只要B发出确认,新的连接就建立了。

由于现在A并没有发出建立连接的请求,因此不会理睬B的确认,也不会向B发送数据。但B却以为新的运输连接已经建立了,并一直等待A发来数据。B的许多资源就这样白白浪费了。

采用三次握手的办法可以防止上述现象的发生。例如在刚才的情况下,A不会向B的确认发出确认。B由于收不到确认,就知道A并没有要求建立连接。

(3)四次挥手

数据传输结束后,通信的双方都可释放连接。现在 A 的应用进程先向其 TCP 发出连接释放报文段,并停止再发送数据,主动关闭 TCP连接。

  • A 把连接释放报文段首部的 FIN = 1,其序号 seq = u,等待 B 的确认。
  • B 发出确认,确认号 ack = u+1,而这个报文段自己的序号 seq = v。(TCP 服务器进程通知高层应用进程)。
  • 从 A 到 B 这个方向的连接就释放了,TCP 连接处于半关闭状态。A 不能向 B 发送数据;B 若发送数据,A 仍要接收。
  • 当 B 不再需要连接时,发送连接释放请求报文段,FIN=1。
  • A 收到后发出确认,进入 TIME-WAIT 状态,等待 2 MSL(2*2 = 4 mins)时间后释放连接。
  • B 收到 A 的确认后释放连接。

(4)四次挥手的原因

客户端发送了 FIN 连接释放报文之后,服务器收到了这个报文,就进入了 CLOSE-WAIT 状态。这个状态是为了让服务器端发送还未传送完毕的数据,传送完毕之后,服务器会发送 FIN 连接释放报文。

(5)TIME_WAIT

MSL是Maximum Segment Lifetime英文的缩写,中文可以译为 “报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。2MSL = 2*2mins = 4mins

客户端接收到服务器端的 FIN 报文后进入此状态,此时并不是直接进入 CLOSED 状态,还需要等待一个时间计时器设置的时间 2MSL。这么做有两个理由:

  • 确保最后一个确认报文段能够到达。如果 B 没收到 A 发送来的确认报文段,那么就会重新发送连接释放请求报文段,A 等待一段时间就是为了处理这种情况的发生。

  • 等待一段时间是为了让本连接持续时间内所产生的所有报文段都从网络中消失,使得下一个新的连接不会出现旧的连接请求报文段。

(6)如何保证可靠传输

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

(7)TCP连接状态?

  • CLOSED:初始状态。
  • LISTEN:服务器处于监听状态。
  • SYN_SEND:客户端socket执行CONNECT连接,发送SYN包,进入此状态。
  • SYN_RECV:服务端收到SYN包并发送服务端SYN包,进入此状态。
  • ESTABLISH:表示连接建立。客户端发送了最后一个ACK包后进入此状态,服务端接收到ACK包后进入此状态。
  • FIN_WAIT_1:终止连接的一方(通常是客户机)发送了FIN报文后进入。等待对方FIN。
  • CLOSE_WAIT:(假设服务器)接收到客户机FIN包之后等待关闭的阶段。在接收到对方的FIN包之后,自然是需要立即回复ACK包的,表示已经知道断开请求。但是本方是否立即断开连接(发送FIN包)取决于是否还有数据需要发送给客户端,若有,则在发送FIN包之前均为此状态。
  • FIN_WAIT_2:此时是半连接状态,即有一方要求关闭连接,等待另一方关闭。客户端接收到服务器的ACK包,但并没有立即接收到服务端的FIN包,进入FIN_WAIT_2状态。
  • LAST_ACK:服务端发动最后的FIN包,等待最后的客户端ACK响应,进入此状态。
  • TIME_WAIT:客户端收到服务端的FIN包,并立即发出ACK包做最后的确认,在此之后的2MSL时间称为TIME_WAIT状态。

(8)TCP和HTTP

4. TCP连接中如果断电怎么办

TCP是一种有连接的协议,但是这个连接并不是指有一条实际的电路,而是一种虚拟的电路。TCP的建立连接和断开连接都是通过发送数据实现的,也就是我们常说的三次握手、四次挥手。TCP两端保存了一种数据的状态,就代表这种连接,TCP两端之间的路由设备只是将数据转发到目的地,并不知道这些数据实际代表了什么含义,也并没有在其中保存任何的状态信息,也就是说中间的路由设备没有什么连接的概念,只是将数据转发到目的地,只有数据的发送者和接受者两端真正的知道传输的数据代表着一条连接。

但是这就说明了一点,如果不发送数据那么是无法断开连接的。正常情况下当TCP的一端A调用了SOCKET的close或者进程结束,操作系统就会按照TCP协议发送FIN数据报文。B端收到后就会断开连接。但是当出现了上文所说的异常情况时:被拔掉网线或者断掉电源,总结起来就是没有机会发出断开的FIN数据报文。那么和A直连的路由设备虽然知道A设备已经断开了,但是路由设备并没有保存连接的状态信息,所以路由设备也就不可能去通知B端A端的断开。而B端没有收到断开的数据报文就会依然保持连接。所以A端拔掉网线或者断掉电源后B端是没办法收到断开连接的通知的。

保持连接并不是毫无代价的,如果这种异常断开的连接有很多,那么势必会耗费大量的资源,必须要想办法检测出这种异常连接。
检测的方法很简单,只要让B端主动通过这个连接向A端继续发送数据即可。上文说过,A端异常断开后,和A端直接连接的路由器是知道的。当B端发送的数据经过转发后到达这个路由器后,必然最终会返回B端一个目的不可达。此时B端立刻就会知道这条连接其实已经异常断开了。
但是B端不可能知道什么时候会出现这种异常,所以B端必须定时发送数据来检测连接是否异常断开。数据的内容无关紧要,任何数据都能达到这个效果。这个数据就是我们经常在TCP编程中所说的心跳。

TCP协议本身就提供了一种这样的机制来探测对端的存活。TCP协议有一个KEEP_LIVE开关,只要打开这个开关就会定时发送一些数据长度为零的探测心跳包,发送的频率和次数都可以设置,具体的方法在网上搜索tcp keepalive即可,网上有很多文章,这里不再赘述。

除了使用TCP协议本身的保活开关机制,还可以在应用层主动发送心跳数据包,那么在应用层主动发送心跳数据包的方式和TCP协议本身的保活机制有什么区别呢?

应用层的心跳数据包会耗费更多的带宽,因为TCP协议的保活机制发送的是数据长度为零心跳包,而应用层的心跳数据包长度则必然会大于0。应用层的心跳数据包可以带一些应用所需要的数据,随应用自己控制,而TCP协议的保活机制则是对于应用层透明的,无法利用心跳携带数据。

如果只是一端向另一端发送心跳就行了呢?显然不行。因为两端都有可能发生异常断开的情况。所以TCP连接的两端必须都向对端发送心跳。TCP中不使用心跳通常来说并没有什么问题,但是一旦遇到了连接异常断开,那么就会出现问题。所以任何一个完善的TCP应用都应该使用心跳。

5. TCP和UDP区别?如何改进TCP

  • TCP和UDP区别
    • UDP 是无连接的,即发送数据之前不需要建立连接。
    • UDP 使用尽最大努力交付,即不保证可靠交付,同时也不使用拥塞控制。
    • UDP 是面向报文的。UDP 没有拥塞控制,很适合多媒体通信的要求。
    • UDP 支持一对一、一对多、多对一和多对多的交互通信。
    • UDP 的首部开销小,只有 8 个字节。
    • TCP 是面向连接的运输层协议。
    • 每一条 TCP 连接只能有两个端点(endpoint),每一条 TCP 连接只能是点对点的(一对一)。
    • TCP 提供可靠交付的服务。
    • TCP 提供全双工通信。
    • TCP是面向字节流。  
    • 首部最低20个字节。
  • TCP加快传输效率的方法
    • 采取一块确认的机制

6. TCP滑动窗口


窗口是缓存的一部分,用来暂时存放字节流。发送方和接收方各有一个窗口,接收方通过 TCP 报文段中的窗口字段告诉发送方自己的窗口大小,发送方根据这个值和其它信息设置自己的窗口大小

发送窗口内的字节都允许被发送,接收窗口内的字节都允许被接收。如果发送窗口左部的字节已经发送并且收到了确认,那么就将发送窗口向右滑动一定距离,直到左部第一个字节不是已发送并且已确认的状态;接收窗口的滑动类似,接收窗口左部字节已经发送确认并交付主机,就向右滑动接收窗口。

接收窗口只会对窗口内最后一个按序到达的字节进行确认,例如接收窗口已经收到的字节为 {31, 34, 35},其中 {31} 按序到达,而 {32, 33} 就不是,因此只对字节 31 进行确认。发送方得到一个字节的确认之后,就知道这个字节之前的所有字节都已经被接收。

以下进行滑动窗口模拟

在 TCP 中,滑动窗口是为了实现流量控制。如果对方发送数据过快,接收方就来不及接收,接收方就需要通告对方,减慢数据的发送。

  • 发送方接收到了对方发来的报文 ack = 33, win = 10,知道对方收到了 33 号前的数据,现在期望接收 [33, 43) 号数据。发送方连续发送了 4 个报文段假设为 A, B, C, D, 分别携带 [33, 35), [35, 36), [36, 38), [38, 41) 号数据。

  • 接收方接收到了报文段 A, C,但是没收到 B 和 D,也就是只收到了 [33, 35) 和 [36, 38) 号数据。接收方发送回对报文段 A 的确认:ack = 35, win = 10。

  • 发送方收到了 ack = 35, win = 10,对方期望接收 [35, 45) 号数据。接着发送了一个报文段 E,它携带了 [41, 44) 号数据。

  • 接收方接收到了报文段 B: [35, 36), D:[38, 41),接收方发送对 D 的确认:ack = 41, win = 10. (这是一个累积确认)

  • 发送方收到了 ack = 41, win = 10,对方期望接收 [41, 51) 号数据。

  • ……

  • 需要注意的是,接收方接收 tcp 报文的顺序是不确定的,并非是一定先收到 35 再收到 36,也可能是先收到 36,37,再收到 35.

7. TCP流量控制

流量控制是为了控制发送方发送速率,保证接收方来得及接收。

接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。

8. TCP拥塞处理(Congestion Handling)

拥塞控制的一般原理

  • 在某段时间,若对网络中某资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏——产生拥塞(congestion)。
  • 出现资源拥塞的条件:对资源需求的总和 > 可用资源
  • 若网络中有许多资源同时产生拥塞,网络的性能就要明显变坏,整个网络的吞吐量将随输入负荷的增大而下降。

如果网络出现拥塞,分组将会丢失,此时发送方会继续重传,从而导致网络拥塞程度更高。因此当出现拥塞时,应当控制发送方的速率。这一点和流量控制很像,但是出发点不同。流量控制是为了让接收方能来得及接收,而拥塞控制是为了降低整个网络的拥塞程度。

TCP 主要通过四种算法来进行拥塞控制:慢开始、拥塞避免、快重传、快恢复。

发送方需要维护一个叫做拥塞窗口(cwnd)的状态变量,注意拥塞窗口与发送方窗口的区别:拥塞窗口只是一个状态变量,实际决定发送方能发送多少数据的是发送方窗口。

为了便于讨论,做如下假设:

  • 接收方有足够大的接收缓存,因此不会发生流量控制;
  • 虽然 TCP 的窗口基于字节,但是这里设窗口的大小单位为报文段。

(1)慢开始与拥塞避免

发送的最初执行慢开始,令 cwnd=1,发送方只能发送 1 个报文段;当收到确认后,将 cwnd 加倍,因此之后发送方能够发送的报文段数量为:2、4、8 …

注意到慢开始每个轮次都将 cwnd 加倍,这样会让 cwnd 增长速度非常快,从而使得发送方发送的速度增长速度过快,网络拥塞的可能也就更高。设置一个慢启动阈值 ssthresh,当 cwnd >= ssthresh 时,进入拥塞避免,每个轮次只将 cwnd 加 1。

如果出现了超时,则令 ssthresh = cwnd/2,然后重新执行慢开始。

(2)快重传与快恢复

在接收方,要求每次接收到报文段都应该对最后一个已收到的有序报文段进行确认。例如已经接收到 M1 和 M2,此时收到 M4,应当发送对 M2 的确认。

在发送方,如果收到三个重复确认,那么可以知道下一个报文段丢失,此时执行快重传,立即重传下一个报文段。例如收到三个 M2,则 M3 丢失,立即重传 M3。

在这种情况下,只是丢失个别报文段,而不是网络拥塞。因此执行快恢复,令 ssthresh = cwnd/2 ,cwnd = ssthresh,注意到此时直接进入拥塞避免。慢开始和快恢复的快慢指的是 cwnd 的设定值,而不是 cwnd 的增长速率。慢开始 cwnd 设定为 1,而快恢复 cwnd 设定为 ssthresh。

(3)发送窗口的上限值

发送方的发送窗口的上限值应当取为接收方窗口 rwnd 和拥塞窗口 cwnd 这两个变量中较小的一个,即应按以下公式确定:

  • 发送窗口的上限值 = Min {rwnd, cwnd}
    • 当 rwnd < cwnd 时,是接收方的接收能力限制发送窗口的最大值。
    • 当 cwnd < rwnd 时,则是网络的拥塞限制发送窗口的最大值。

9. 如何区分流量控制和拥塞控制

  • 拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷。
  • 拥塞控制是一个全局性的过程,涉及到所有的主机、所有的路由器,以及与降低网络传输性能有关的所有因素。
  • 流量控制往往指在给定的发送端和接收端之间的点对点通信量的控制。
  • 流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收。

  • 流量控制属于通信双方协商;拥塞控制涉及通信链路全局。

  • 流量控制需要通信双方各维护一个发送窗、一个接收窗,对任意一方,接收窗大小由自身决定,发送窗大小由接收方响应的TCP报文段中窗口值确定;拥塞控制的拥塞窗口大小变化由试探性发送一定数据量数据探查网络状况后而自适应调整。

  • 实际最终发送窗口 = min{流控发送窗口,拥塞窗口}。

10. 解释RTO,RTT和超时重传

  • 超时重传:发送端发送报文后若长时间未收到确认的报文则需要重发该报文。可能有以下几种情况:
    • 发送的数据没能到达接收端,所以对方没有响应。
    • 接收端接收到数据,但是ACK报文在返回过程中丢失。
    • 接收端拒绝或丢弃数据。
  • RTO:从上一次发送数据,因为长期没有收到ACK响应,到下一次重发之间的时间。就是重传间隔。
    • 通常每次重传RTO是前一次重传间隔的两倍,计量单位通常是RTT。例:1RTT,2RTT,4RTT,8RTT……
    • 重传次数到达上限之后停止重传。
  • RTT:数据从发送到接收到对方响应之间的时间间隔,即数据报在网络中一个往返用时。大小不稳定。

11. 停止等待和超时重传

(1). 停止等待

通常我们说如果A和B双方建立好tcp连接后就可以相互发送数据了,A为发送方,B为接收方。因为这里讨论可靠传输原理,所以把传输的数据单元称为分组。“停止等待”就是每发送完一个分组就停止发送,等待对方确认后再发送下一个分组。停止等待协议考虑了数据在网络中传输出现的几种情况来提供有效措施保障数据的可靠传输,下面我们就一一来介绍这几种情况。

  • 出现差错或丢失的情况

当A在发送M1分组的过程中丢失时,又或者B接收到M1分组检测到差错并丢弃了M1分组时(注意:这里B不会发送M1确认分组,而是什么也不做),可靠传输协议是这样设计的:只要A没有在规定时间内收到B的确认,就认为刚才发送的分组丢失了,并对丢失的分组进行重传,这种方式叫超时重传。要实现超时重传,就要每发送完一个分组就设置一个超时计时器。如果在超时计时器到期之前收到了对方的确认,则撤销该超时计时器。

这里注意几点:

  1. A发送完一个分组后,必须暂时存储已发送的分组的副本(发生超时重传时使用),当收到该分组的确认时就清除本地存储的分组的副本。

  2. 分组和确认分组都必须进行编号,这样才能明确哪一个已发送的分组被确认,哪一个还没被确认。

  3. 超时计时器设置的重传时间比数据分组传输的平均往返时间更长一些,在设置重传时间也是有要求的。因为重传时间设置的过长会导致重传花费的时间长,通信效率慢,但是重传时间设置的过短会导致出现不必要的重传,浪费网络资源。

比如B发送的确认分组发生在网络中发生拥塞,传输的时间过长才到达A,但是A设置的重传时间又很短,就会出现不必要的重传。因此设置重传时间是非常复杂的,因为分组在网络传输的过程中经过哪些网络,是否会出现网络拥塞或其他问题,都是不确定的。

  • 确认丢失的情况

当B收到A的M1分组后,B发送的M1确认分组在网络中丢失了,且A在设定的超时重传时间内又没有收到B的M1确认分组,这时A无法知道是自己发送的M1分组出错丢失,还是B发送的M1确认分组丢失了,那么A会在超时计时器到期后重传M1分组。

如果B又收到了重传的分组M1,这时B会丢弃重复的M1分组,并向A发送M1确认分组(很明显,因为A本来就没有收到过确认啊)。

  • 确认迟到的情况

这里我们需要假设这么一种情况:A在发送M1分组后,B发送的确认M1分组却迟到了,但是A在超时计时器规定的时间内又没有收到B的确认M1分组,那么A将会重传M1分组,根据前面所知的情况来看,B在收到重复的M1分组后会丢弃并重传确认M1分组。那么在A收到重传的确认分组后,又收到了B迟到的确认M1分组,这是A会丢弃迟到的确认M1分组。

像上面所说的可靠传输协议通常称为自动重传请求,也就是说,重传时自动进行的,只要发送方没收到确认,就会重传。如果A不断重传分组却总是也收不到确认,这说明通信线路太差,不能进行通信。这是上面所有停止等待的情况.

(2). 超时重传

原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止。 
影响超时重传机制协议效率的一个关键参数是重传超时时间(RTO,Retransmission TimeOut)。

RTO的值被设置过大过小都会对协议造成不利影响。 

  • RTO设长了,重发就慢,没有效率,性能差。 
  • RTO设短了,重发的就快,会增加网络拥塞,导致更多的超时,更多的超时导致更多的重发。 

连接往返时间(RTT,Round Trip Time),指发送端从发送TCP包开始到接收它的立即响应所消耗的时间。

12. 从输入网址到获得页面的网络请求过程

  • 查询 DNS
    • 浏览器搜索自身的DNS缓存
    • 搜索操作系统的DNS缓存,本地host文件查询
    • 如果 DNS 服务器和我们的主机在同一个子网内,系统会按照下面的 ARP 过程对 DNS 服务器进行 ARP查询
    • 如果 DNS 服务器和我们的主机在不同的子网,系统会按照下面的 ARP 过程对默认网关进行查询
  • 浏览器获得域名对应的IP地址后,发起HTTP三次握手

  • TCP/IP连接建立起来后,浏览器就可以向服务器发送HTTP请求了

  • TLS 握手

    • 客户端发送一个 ClientHello 消息到服务器端,消息中同时包含了它的 Transport Layer Security (TLS) 版本,可用的加密算法和压缩算法.
    • 服务器端向客户端返回一个 ServerHello 消息,消息中包含了服务器端的TLS版本,服务器所选择的加密和压缩算法,以及数字证书认证机构.(Certificate Authority,缩写 CA)签发的服务器公开证书,证书中包含了公钥。客户端会使用这个公钥加密接下来的握手过程,直到协商生成一个新的对称密钥.
    • 客户端根据自己的信任CA列表,验证服务器端的证书是否可信。如果认为可信,客户端会生成一串伪随机数,使用服务器的公钥加密它。这串随机数会被用于生成新的对称密钥.
    • 服务器端使用自己的私钥解密上面提到的随机数,然后使用这串随机数生成自己的对称主密钥.
    • 客户端发送一个 Finished 消息给服务器端,使用对称密钥加密这次通讯的一个散列值.
    • 服务器端生成自己的 hash 值,然后解密客户端发送来的信息,检查这两个值是否对应。如果对应,就向客户端发送一个 Finished 消息,也使用协商好的对称密钥加密.
    • 从现在开始,接下来整个 TLS 会话都使用对称秘钥进行加密,传输应用层(HTTP)内容.
  • HTTP 服务器请求处理.

    HTTPD(HTTP Daemon)在服务器端处理请求/响应。最常见的 HTTPD 有 Linux 上常用的 Apache 和 nginx,以及 Windows 上的 IIS。

    • HTTPD 接收请求

      • 服务器把请求拆分为以下几个参数:

      HTTP 请求方法(GET, POST, HEAD, PUT, DELETE, CONNECT, OPTIONS, 或者 TRACE)。直接在地址栏中输入 URL 这种情况下,使用的是 GET 方法域名:google.com请求路径/页面:/ (我们没有请求google.com下的指定的页面,因此 / 是默认的路径)

    • 服务器验证其上已经配置了 google.com 的虚拟主机

    • 服务器验证 google.com 接受 GET 方法

    • 服务器验证该用户可以使用 GET 方法(根据 IP 地址,身份信息等)

    • 如果服务器安装了 URL 重写模块(例如 Apache 的 mod_rewrite 和 IIS 的 URL Rewrite),服务器会尝试匹配重写规则,如果匹配上的话,服务器会按照规则重写这个请求

    • 服务器根据请求信息获取相应的响应内容,这种情况下由于访问路径是 “/” ,会访问首页文件(你可以重写这个规则,但是这个是最常用的)。

    • 服务器会使用指定的处理程序分析处理这个文件,假如 Google 使用 PHP,服务器会使用 PHP 解析 index 文件,并捕获输出,把 PHP 的输出结果返回给请求者

  • 服务器接受到这个请求,根据路径参数,经过后端的一些处理生成HTML页面代码返回给浏览器

  • 浏览器拿到完整的HTML页面代码开始解析和渲染,如果遇到引用的外部js,CSS,图片等静态资源,它们同样也是一个个的HTTP请求,都需要经过上面的步骤

  • 浏览器根据拿到的资源对页面进行渲染,最终把一个完整的页面呈现给用户

超详细版本请转向阅读:what-happens-when-zh_CN

第二部分:应用层(HTTP)

1. URL、URI、URN区别

  • URI(Uniform Resource Identifier,统一资源标识符)

    web服务器资源的名字,例如: index.html

  • URL(Uniform Resource Locator,统一资源定位符)

  • URN(Uniform Resource Name,统一资源名称),例如 urn:isbn:0-486-27557-4。

URI 包含 URL 和 URN,目前 WEB 只有 URL 比较流行,所以见到的基本都是 URL。

2. HTTP的请求和响应报文

(1)请求报文

(2)响应报文

3. HTTP状态

服务器返回的 响应报文 中第一行为状态行,包含了状态码以及原因短语,用来告知客户端请求的结果。

状态码 类别 原因短语
1XX Informational(信息性状态码) 接收的请求正在处理
2XX Success(成功状态码) 请求正常处理完毕
3XX Redirection(重定向状态码) 需要进行附加操作以完成请求
4XX Client Error(客户端错误状态码) 服务器无法处理请求
5XX Server Error(服务器错误状态码) 服务器处理请求出错

(1)1XX 信息

  • 100 Continue :表明到目前为止都很正常,客户端可以继续发送请求或者忽略这个响应。

(2)2XX 成功

  • 200 OK
  • 204 No Content :请求已经成功处理,但是返回的响应报文不包含实体的主体部分。一般在只需要从客户端往服务器发送信息,而不需要返回数据时使用。
  • 206 Partial Content :表示客户端进行了范围请求。响应报文包含由 Content-Range 指定范围的实体内容。

(3)3XX 重定向

  • 301 Moved Permanently :永久性重定向
  • 302 Found :临时性重定向
  • 303 See Other :和 302 有着相同的功能,但是 303 明确要求客户端应该采用 GET 方法获取资源。
  • 注:虽然 HTTP 协议规定 301、302 状态下重定向时不允许把 POST 方法改成 GET 方法,但是大多数浏览器都会在 301、302 和 303 状态下的重定向把 POST 方法改成 GET 方法。
  • 304 Not Modified :如果请求报文首部包含一些条件,例如:If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,如果不满足条件,则服务器会返回 304 状态码。
  • 307 Temporary Redirect :临时重定向,与 302 的含义类似,但是 307 要求浏览器不会把重定向请求的 POST 方法改成 GET 方法。

(4)4XX 客户端错误

  • 400 Bad Request :请求报文中存在语法错误。
  • 401 Unauthorized :该状态码表示发送的请求需要有认证信息(BASIC 认证、DIGEST 认证)。如果之前已进行过一次请求,则表示用户认证失败。
  • 403 Forbidden :请求被拒绝,服务器端没有必要给出拒绝的详细理由。
  • 404 Not Found

(5)5XX 服务器错误

  • 500 Internal Server Error :服务器正在执行请求时发生错误。
  • 502 Bad Gateway : 是用来表示代理或网关在处理请求时发生了错误,并不一定是原始服务器出现了问题
  • 503 Service Unavailable :服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。
  • 504 Gateway Timeout:作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。 

注意:某些代理服务器在DNS查询超时时会返回400或者500错误。

4. HTTP方法

客户端发送的 请求报文 第一行为请求行,包含了方法字段。

(1)GET

获取资源

当前网络请求中,绝大部分使用的是 GET 方法。

(2)HEAD

获取报文首部

和 GET 方法一样,但是不返回报文实体主体部分。

主要用于确认 URL 的有效性以及资源更新的日期时间等。

(3)POST

传输实体主体

POST 主要用来传输数据,而 GET 主要用来获取资源。

更多 POST 与 GET 的比较请见第八章。

(4)PUT

上传文件

由于自身不带验证机制,任何人都可以上传文件,因此存在安全性问题,一般不使用该方法。

PUT /new.html HTTP/1.1
Host: example.com
Content-type: text/html
Content-length: 16

<p>New File</p>

(5)PATCH

对资源进行部分修改

PUT 也可以用于修改资源,但是只能完全替代原始资源,PATCH 允许部分修改。

PATCH /file.txt HTTP/1.1
Host: www.example.com
Content-Type: application/example
If-Match: "e0023aa4e"
Content-Length: 100

[description of changes]

(6)DELETE

删除文件

与 PUT 功能相反,并且同样不带验证机制。

DELETE /file.html HTTP/1.1

(7)OPTIONS

查询支持的方法

查询指定的 URL 能够支持的方法。

会返回 Allow: GET, POST, HEAD, OPTIONS 这样的内容。

(8)CONNECT

要求在与代理服务器通信时建立隧道

使用 SSL(Secure Sockets Layer,安全套接层)和 TLS(Transport Layer Security,传输层安全)协议把通信内容加密后经网络隧道传输。

CONNECT www.example.com:443 HTTP/1.1

(9)TRACE

追踪路径

服务器会将通信路径返回给客户端。

发送请求时,在 Max-Forwards 首部字段中填入数值,每经过一个服务器就会减 1,当数值为 0 时就停止传输。

通常不会使用 TRACE,并且它容易受到 XST 攻击(Cross-Site Tracing,跨站追踪)。

5. GET和POST的区别?

  • GET 被强制服务器支持
  • 浏览器对URL的长度有限制,所以GET请求不能代替POST请求发送大量数据
  • GET请求发送数据更小
  • GET请求是不安全的
  • GET请求是幂等的
    • 幂等的意味着对同一URL的多个请求应该返回同样的结果
  • POST请求不能被缓存
  • POST请求相对GET请求是「安全」的
    • 这里安全的含义仅仅是指是非修改信息
  • GET用于信息获取,而且是安全的和幂等的.
    • 所谓安全的意味着该操作用于获取信息而非修改信息。换句话说,GET 请求一般不应产生副作用。就是说,它仅仅是获取资源信息,就像数据库查询一样,不会修改,增加数据,不会影响资源的状态。
  • POST是用于修改服务器上的资源的请求
  • 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠

引申:说完原理性的问题,我们从表面上来看看GET和POST的区别:

  • GET是从服务器上获取数据,POST是向服务器传送数据。 GET和 POST只是一种传递数据的方式,GET也可以把数据传到服务器,他们的本质都是发送请求和接收结果。只是组织格式和数据量上面有差别,http协议里面有介绍
  • GET是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。POST是通过HTTP POST机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。 因为GET设计成传输小数据,而且最好是不修改服务器的数据,所以浏览器一般都在地址栏里面可以看到,但POST一般都用来传递大数据,或比较隐私的数据,所以在地址栏看不到,能不能看到不是协议规定,是浏览器规定的。
  • 对于GET方式,服务器端用Request.QueryString获取变量的值,对于POST方式,服务器端用Request.Form获取提交的数据。 没明白,怎么获得变量和你的服务器有关,和GET或POST无关,服务器都对这些请求做了封装
  • GET传送的数据量较小,不能大于2KB。POST传送的数据量较大,一般被默认为不受限制。但理论上,IIS4中最大量为80KB,IIS5中为100KB。 POST基本没有限制,我想大家都上传过文件,都是用POST方式的。只不过要修改form里面的那个type参数
  • GET安全性非常低,POST安全性较高。 如果没有加密,他们安全级别都是一样的,随便一个监听器都可以把所有的数据监听到。

6. 如何理解HTTP协议是无状态的

HTTP协议是无状态的(stateless),指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。也就是说,打开一个服务器上的网页和上一次打开这个服务器上的网页之间没有任何联系。
HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。

缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

7. 什么是短连接和长连接

在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协议的长连接和短连接。

8. Cookie

HTTP 协议是无状态的,主要是为了让 HTTP 协议尽可能简单,使得它能够处理大量事务。HTTP/1.1 引入 Cookie 来保存状态信息。

Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。它用于告知服务端两个请求是否来自同一浏览器,并保持用户的登录状态。

(1)用途

  • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
  • 个性化设置(如用户自定义设置、主题等)
  • 浏览器行为跟踪(如跟踪分析用户行为等)

Cookie 曾一度用于客户端数据的存储,因为当时并没有其它合适的存储办法而作为唯一的存储手段,但现在随着现代浏览器开始支持各种各样的存储方式,Cookie 渐渐被淘汰。由于服务器指定 Cookie 后,浏览器的每次请求都会携带 Cookie 数据,会带来额外的性能开销(尤其是在移动环境下)。新的浏览器 API 已经允许开发者直接将数据存储到本地,如使用 Web storage API (本地存储和会话存储)或 IndexedDB。

(2)创建过程

服务器发送的响应报文包含Set-Cookie 首部字段,客户端得到响应报文后把 Cookie 内容保存到浏览器中。

HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry

[page content]

客户端之后对同一个服务器发送请求时,会从浏览器中读出 Cookie 信息通过 Cookie 请求首部字段发送给服务器。

GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry

(3)分类

  • 会话期 Cookie:浏览器关闭之后它会被自动删除,也就是说它仅在会话期内有效。
  • 持久性 Cookie:指定一个特定的过期时间(Expires)或有效期(max-age)之后就成为了持久性的 Cookie。
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

(4)JavaScript 获取 Cookie

通过 Document.cookie 属性可创建新的 Cookie,也可通过该属性访问非 HttpOnly 标记的 Cookie。

document.cookie = "yummy_cookie=choco";
document.cookie = "tasty_cookie=strawberry";
console.log(document.cookie);

(5)Secure 和 HttpOnly

标记为 Secure 的 Cookie 只应通过被 HTTPS 协议加密过的请求发送给服务端。但即便设置了 Secure 标记,敏感信息也不应该通过 Cookie 传输,因为 Cookie 有其固有的不安全性,Secure 标记也无法提供确实的安全保障。

标记为 HttpOnly 的 Cookie 不能被 JavaScript 脚本调用。因为跨域脚本 (XSS) 攻击常常使用 JavaScript 的 Document.cookieAPI 窃取用户的 Cookie 信息,因此使用 HttpOnly 标记可以在一定程度上避免 XSS 攻击。

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly

(6)作用域

Domain 标识指定了哪些主机可以接受 Cookie。如果不指定,默认为当前文档的主机(不包含子域名)。如果指定了 Domain,则一般包含子域名。例如,如果设置 Domain=mozilla.org,则 Cookie 也包含在子域名中(如 developer.mozilla.org)。

Path 标识指定了主机下的哪些路径可以接受 Cookie(该 URL 路径必须存在于请求 URL 中)。以字符 %x2F (“/”) 作为路径分隔符,子路径也会被匹配。例如,设置 Path=/docs,则以下地址都会匹配:

  • /docs
  • /docs/Web/
  • /docs/Web/HTTP

9. Session

除了可以将用户信息通过 Cookie 存储在用户浏览器中,也可以利用 Session 存储在服务器端,存储在服务器端的信息更加安全。

Session 可以存储在服务器上的文件、数据库或者内存中,现在最常见的是将 Session 存储在内存型数据库中,比如 Redis。

使用 Session 维护用户登录的过程如下:

  • 用户进行登录时,用户提交包含用户名和密码的表单,放入 HTTP 请求报文中;
  • 服务器验证该用户名和密码;
  • 如果正确则把用户信息存储到 Redis 中,它在 Redis 中的 ID 称为 Session ID;
  • 服务器返回的响应报文的 Set-Cookie 首部字段包含了这个 Session ID,客户端收到响应报文之后将该 Cookie 值存入浏览器中;
  • 客户端之后对同一个服务器进行请求时会包含该 Cookie 值,服务器收到之后提取出 Session ID,从 Redis 中取出用户信息,继续之后的业务操作。

应该注意 Session ID 的安全性问题,不能让它被恶意攻击者轻易获取,那么就不能产生一个容易被猜到的 Session ID 值。此外,还需要经常重新生成 Session ID。在对安全性要求极高的场景下,例如转账等操作,除了使用 Session 管理用户状态之外,还需要对用户进行重新验证,比如重新输入密码,或者使用短信验证码等方式。

10. 浏览器禁用 Cookie

此时无法使用 Cookie 来保存用户信息,只能使用 Session。除此之外,不能再将 Session ID 存放到 Cookie 中,而是使用 URL 重写技术,将 Session ID 作为 URL 的参数进行传递。

11. Cookie 与 Session 选择

  • Cookie 只能存储 ASCII 码字符串,而 Session 则可以存取任何类型的数据,因此在考虑数据复杂性时首选 Session;
  • Cookie 存储在浏览器中,容易被恶意查看。如果非要将一些隐私数据存在 Cookie 中,可以将 Cookie 值进行加密,然后在服务器进行解密;
  • 对于大型网站,如果用户所有的信息都存储在 Session 中,那么开销是非常大的,因此不建议将所有的用户信息都存储到 Session 中。

12. HTTPs安全性

HTTP 有以下安全性问题:

  • 使用明文进行通信,内容可能会被窃听;
  • 不验证通信方的身份,通信方的身份有可能遭遇伪装;
  • 无法证明报文的完整性,报文有可能遭篡改。

HTTPs(Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲HTTPs是HTTP的安全版。

HTTPs 并不是新协议,而是让 HTTP 先和 SSL(Secure Sockets Layer)通信,再由 SSL 和 TCP 通信。也就是说 HTTPs 使用了隧道进行通信。

通过使用 SSL,HTTPs 具有了加密(防窃听)、认证(防伪装)和完整性保护(防篡改)。

(1)对称密钥加密

对称密钥加密(Symmetric-Key Encryption),加密和解密使用同一密钥。

  • 优点:运算速度快;
  • 缺点:无法安全地将密钥传输给通信方。

(2)非对称密钥加密

非对称密钥加密,又称公开密钥加密(Public-Key Encryption),加密和解密使用不同的密钥。

公开密钥所有人都可以获得,通信发送方获得接收方的公开密钥之后,就可以使用公开密钥进行加密,接收方收到通信内容后使用私有密钥解密。

非对称密钥除了用来加密,还可以用来进行签名。因为私有密钥无法被其他人获取,因此通信发送方使用其私有密钥进行签名,通信接收方使用发送方的公开密钥对签名进行解密,就能判断这个签名是否正确。

  • 优点:可以更安全地将公开密钥传输给通信发送方;
  • 缺点:运算速度慢。

(3)HTTPs 采用的加密方式

HTTPs 采用混合的加密机制,使用非对称密钥加密用于传输对称密钥来保证安全性,之后使用对称密钥加密进行通信来保证效率。

13. SSL/TLS协议的握手过程

我们知道,HTTP 协议都是明文传输内容,在早期只展示静态内容时没有问题。伴随着互联网的快速发展,人们对于网络传输安全性的要求也越来越高,HTTPS 协议因此出现。如上图所示,在 HTTPS 加密中真正起作用的其实是 SSL/TLS 协议。SSL/TLS 协议作用在 HTTP 协议之下,对于上层应用来说,原来的发送接收数据流程不变,这就很好地兼容了老的 HTTP 协议,这也是软件开发中分层实现的体现。

SSL (Secure Socket Layer,安全套接字层)

SSL为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取,当前为3.0版本。

SSL协议可分为两层: SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。 SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。

TLS (Transport Layer Security,传输层安全协议)

用于两个应用程序之间提供保密性和数据完整性。
TLS 1.0是IETF(Internet Engineering Task Force,Internet工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本,可以理解为SSL 3.1,它是写入了 RFC 的。该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。较低的层为 TLS 记录协议,位于某个可靠的传输协议(例如 TCP)上面。

SSL/TLS 握手是为了安全地协商出一份对称加密的秘钥,这个过程很有意思,下面我们一起来了解一下。

(1)client hello

握手第一步是客户端向服务端发送 Client Hello 消息,这个消息里包含了一个客户端生成的随机数 Random1、客户端支持的加密套件(Support Ciphers)和 SSL Version 等信息。

(2)server hello

第二步是服务端向客户端发送 Server Hello 消息,这个消息会从 Client Hello 传过来的 Support Ciphers 里确定一份加密套件,这个套件决定了后续加密和生成摘要时具体使用哪些算法,另外还会生成一份随机数 Random2。注意,至此客户端和服务端都拥有了两个随机数(Random1+ Random2),这两个随机数会在后续生成对称秘钥时用到。

(3)server certificate

这一步是服务端将自己的证书下发给客户端,让客户端验证自己的身份,客户端验证通过后取出证书中的公钥。

(4)Server Hello Done

Server Hello Done 通知客户端 Server Hello 过程结束。

(5)Client Key Exchange

上面客户端根据服务器传来的公钥生成了 PreMaster Key,Client Key Exchange 就是将这个 key 传给服务端,服务端再用自己的私钥解出这个 PreMaster Key 得到客户端生成的 Random3。至此,客户端和服务端都拥有 Random1 + Random2 + Random3,两边再根据同样的算法就可以生成一份秘钥,握手结束后的应用层数据都是使用这个秘钥进行对称加密。

为什么要使用三个随机数呢?这是因为 SSL/TLS 握手过程的数据都是明文传输的,并且多个随机数种子来生成秘钥不容易被暴力破解出来。

(6)Change Cipher Spec(Client)

这一步是客户端通知服务端后面再发送的消息都会使用前面协商出来的秘钥加密了,是一条事件消息。

(7)Finished(Client)

客户端发送Finished报文。该报文包含连接至今全部报文的整理校验值。这次握手协议是否能成功,要以服务器是否能够正确解密该报文作为判定标准。

(8)Change Cipher Spec(Server)

服务器同样发送Change Cipher Spec报文给客户端

(9)Finished(Server)

服务器同样发送Finished报文给客户端

(10-11)Application Data

到这里,双方已安全地协商出了同一份秘钥,所有的应用层数据都会用这个秘钥加密后再通过 TCP 进行可靠传输。

(12)Alert:warning, close notify

最后由客户端断开连接。断开连接时,发送close_notify报文。上图做了一些省略,在这步之后再发送一种叫做MAC(Message Authentication Code)的报文摘要。MAC能够查知报文是否遭到篡改,从而保护报文的完整性。

(*)demand client certificate

Certificate Request 是服务端要求客户端上报证书,这一步是可选的,对于安全性要求高的场景会用到。

(*)check server certificate

客户端收到服务端传来的证书后,先从 CA 验证该证书的合法性,验证通过后取出证书中的服务端公钥,再生成一个随机数 Random3,再用服务端公钥非对称加密 Random3 生成 PreMaster Key

14. 数字签名、数字证书、SSL、https是什么关系?

HTTPS 是建立在密码学基础之上的一种安全通信协议,严格来说是基于 HTTP 协议和 SSL/TLS 的组合。理解 HTTPS 之前有必要弄清楚一些密码学的相关基础概念,
比如:明文、密文、密码、密钥、对称加密、非对称加密、信息摘要、数字签名、数字证书。接下来我会逐个解释这些术语,文章里面提到的『数据』、『消息』都是同一个概念,表示用户之间通信的内容载体,此外文章中提到了以下几个角色:

  • Alice:消息发送者
  • Bob:消息接收者
  • Attacker:中间攻击者
  • Trent:第三方认证机构

密码

密码学中的“密码”术语与网站登录时用的密码(password)是不一样的概念,password 翻译过来其实是“口令”,它是用于认证用途的一组文本字符串。

而密码学中的密码(cipher)是一套算法(algorithm),这套算法用于对消息进行加密和解密,从明文到密文的过程称之为加密,密文反过来生成明文称之为解密,加密算法与解密算法合在一起称为密码算法。

密钥

密钥(key)是在使用密码算法过程中输入的一段参数。同一个明文在相同的密码算法和不同的密钥计算下会产生不同的密文。很多知名的密码算法都是公开的,密钥才是决定密文是否安全的重要参数,通常密钥越长,破解的难度越大,比如一个8位的密钥最多有256种情况,使用穷举法,能非常轻易的破解。根据密钥的使用方法,密码可分为对称加密和公钥加密。

对称加密

对称密钥(Symmetric-key algorithm)又称为共享密钥加密,加密和解密使用相同的密钥。常见的对称加密算法有DES、3DES、AES、RC5、RC6。对称密钥的优点是计算速度快,但是它有缺点,接收者需要发送者告知密钥才能解密,因此密钥如何安全的发送给接收者成为了一个问题。

Alice 给 Bob 发送数据时,把数据用对称加密后发送给 Bob,发送过程中由于对数据进行了加密,因此即使有人窃取了数据也没法破解,因为它不知道密钥是什么。但是同样的问题是 Bob 收到数据后也一筹莫展,因为它也不知道密钥是什么,那么 Alice 是不是可以把数据和密钥一同发给 Bob 呢。当然不行,一旦把密钥和密钥一起发送的话,那就跟发送明文没什么区别了,因为一旦有人把密钥和数据同时获取了,密文就破解了。所以对称加密的密钥配是个问题。如何解决呢,公钥加密是一个办法。

公钥加密(非对称加密)

公开密钥加密(public-key cryptography)简称公钥加密,这套密码算法包含配对的密钥对,分为加密密钥和解密密钥。发送者用加密密钥进行加密,接收者用解密密钥进行解密。加密密钥是公开的,任何人都可以获取,因此加密密钥又称为公钥(public key),解密密钥不能公开,只能自己使用,因此它又称为私钥(private key)。常见的公钥加密算法有 RSA。

还是以Alice 给 Bob 发送数据为例,公钥加密算法由接收者 Bob 发起

  1. Bob 生成公钥和私钥对,私钥自己保存,不能透露给任何人。
  2. Bob 把公钥发送给 Alice,发送过程中即使被人窃取也没关系
  3. Alice 用公钥把数据进行加密,并发送给 Bob,发送过程中被人窃取了同样没关系,因为没有配对的私钥进行解密是没法破解的
  4. Bob 用配对的私钥解密。

虽然公钥加密解决了密钥配送的问题,但是你没法确认公钥是不是合法的,Bob 发送的公钥你不能肯定真的是 Bob 发的,因为也有可能在 Bob 把公钥发送给 Alice 的过程中出现中间人攻击,把真实的公钥掉包替换。
而对于 Alice 来说完全不知。还有一个缺点是它的运行速度比对称加密慢很多。

消息摘要

消息摘要(message digest)函数是一种用于判断数据完整性的算法,也称为散列函数或哈希函数,函数返回的值叫散列值,散列值又称为消息摘要或者指纹(fingerprint)。这种算法是一个不可逆的算法,因此你没法通过消息摘要反向推倒出消息是什么。所以它也称为单向散列函数。下载软件时如何确定是官方提供的完整版呢,如果有中间人在软件里面嵌入了病毒,你也不得而知。所以我们可以使用散列函数对消息进行运算,生成散列值,通常软件提供方会同时提供软件的下载地址和软件的散列值,用户把软件下载后在本地用相同的散列算法计算出散列值,与官方提供的散列值对比,如果相同,说明该软件是完成的,否则就是被人修改过了。常用的散列算法有MD5、SHA。

散列函数可以保证数据的完整性,识别出数据是否被篡改,但它并不能识别出数据是不是伪装的,因为中间人可以把数据和消息摘要同时替换,数据虽然是完整的,但真实数据被掉包了,接收者收到的并不是发送者发的,而是中间人的。
消息认证是解决数据真实性的办法。认证使用的技术有消息认证码和数字签名。

消息认证码

消息认证码(message authentication code)是一种可以确认消息完整性并进行认证(消息认证是指确认消息来自正确的发送者)的技术,简称 MAC。消息认证码可以简单理解为一种与密钥相关的单向散列函数。

Alice 给 Bob 发送消息前,先把共享密钥(key)发送给 Bob,Alice 把消息计算出 MAC 值,连同消息一起发送给 Bob,Bob 接收到消息和 MAC 值后,与本地计算得到 MAC 值对比,如果两者相同,就说明消息是完整的,而且可以确定是 Alice 发送的,没有中间人伪造。不过,消息认证码同样会遇到对称加密的密钥配送问题,因此解决密钥配送问题还是要采用公钥加密的方式。

此外,消息认证码还有一个无法解决的问题,Bob 虽然可以识别出消息的篡改和伪装,但是 Alice 可以否认说:“我没发消息,应该是 Bob 的密钥被 Attacker 盗取了,这是 Attacker 发的吧”。Alice 这么说你还真没什么可以反驳的,那么如何防止 Alice 不承认呢,数字签名可以实现。

数字签名

Alice 发邮件找 Bob 借1万钱,因为邮件可以被人篡改(改成10万),也可以被伪造(Alice 根本就没发邮件,而是 Attacker 伪造 Alice 在发邮件),Alice 借了钱之后还可以不承认(不是我借的,我没有签名啊)。

消息认证码可以解决篡改和伪造的问题,Alice 不承认自己借了钱时,Bob 去找第三方机构做公正,即使这样,公正方也没法判断 Alice 有没有真的借钱,因为他们俩共享了密钥,也就是说两个都可以计算出正确的 MAC 值,Bob 说:“明明你发的消息和 MAC 值和我自己生成的 MAC 值一样,肯定是你发的消息”,Alice 说:“你把密钥透露给了其他人,是他发的邮件,你找他去吧”。Alice 矢口否认。

数字签名(Digital Signature)就可以解决否认的问题,发送消息时,Alice 和 Bob 使用不同的密钥,把公钥加密算法反过来使用,发送者 Alice 使用私钥对消息进行签名,而且只能是拥有私钥的 Alice 可以对消息签名,Bob 用配对的公钥去验证签名,第三方机构也可以用公钥验证签名,如果验证通过,说明消息一定是 Alice 发送的,抵赖也不行,因为你只有 Alice 可以生成签名。这就防止了否认的问题。

它的流程是:

第一步:发送者 Alice 把消息哈希函数处理生成消息摘要,摘要信息使用私钥加密之后生成签名,连同消息一起发送给接收者 Bob。

第二步:数据经过网络传输,Bob收到数据后,把签名和消息分别提取出来。

第三步:对签名进行验证,验证的过程是先把消息提取出来做同样的Hash处理,得到消息摘要,再与 Alice 传过来的签名用公钥解密,如果两者相等,就表示签名验证成功,否则验证失败,表示不是 Alice发的。

公钥证书

公钥密码在数字签名技术里面扮演举足轻重的角色,但是如何保证公钥是合法的呢,如果是遭到中间人攻击,掉包怎么办?这个时候公钥就应该交给一个第三方权威机构来管理,这个机构就是认证机构(Certification Authority)CA,CA 把用户的姓名、组织、邮箱地址等个人信息收集起来,还有此人的公钥,并由 CA 提供数字签名生成公钥证书(Public-Key Certificate)PKC,简称证书。

Alice 向 Bob 发送消息时,是通过 Bob 提供的公钥加密后的数据,而 Alice 获取的公钥并不是由 Bob 直接给的,而是由委托一个受信任的第三方机构给的。

  1. Bob 生成密钥对,私钥自己保管,公钥交给认证机构 Trent。
  2. Trent 经过一系列严格的检查确认公钥是 Bob 本人的
  3. Trent 事先也生成自己的一套密钥对,用自己的私钥对 Bob 的公钥进行数字签名并生成数字证书。证书中包含了 Bob 的公钥。公钥在这里是不需要加密的,因为任何人获取 Bob 的公钥都没事,只要确定是 Bob 的公钥就行。
  4. Alice 获取 Trent 提供的证书。
  5. Alice 用 Trent 提供的公钥对证书进行签名验证,签名验证成功就表示证书中的公钥是 Bob 的。
  6. 于是 Alice 就可以用 Bob 提供的公钥对消息加密后发送给 Bob。
  7. Bob 收到密文后,用与之配对的私钥进行解密。

至此,一套比较完善的数据传输方案就完成了。HTTPS(SSL/TLS)就是在这样一套流程基础之上建立起来的。

15. HTTP和HTTPS的区别

  • http是HTTP协议运行在TCP之上。所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。
  • https是HTTP运行在SSL/TLS之上,SSL/TLS运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。此外客户端可以验证服务器端的身份,如果配置了客户端验证,服务器方也可以验证客户端的身份。
  • https协议需要到ca申请证书,一般免费证书很少,需要交费。
  • http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议
  • http和https使用的是完全不同的连接方式用的端口也不一样,前者是80,后者是443。
  • http的连接很简单,是无状态的
  • HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议 要比http协议安全

16. HTTP2.0特性

HTTP/2的通过支持请求与响应的多路复用来减少延迟,通过压缩HTTP首部字段将协议开销降至最低,同时增加对请求优先级和服务器端推送的支持。

(1)二进制分帧

先来理解几个概念:

帧:HTTP/2 数据通信的最小单位消息:指 HTTP/2 中逻辑上的 HTTP 消息。例如请求和响应等,消息由一个或多个帧组成。

流:存在于连接中的一个虚拟通道。流可以承载双向消息,每个流都有一个唯一的整数ID。

HTTP/2 采用二进制格式传输数据,而非 HTTP 1.x 的文本格式,二进制协议解析起来更高效。 HTTP / 1 的请求和响应报文,都是由起始行,首部和实体正文(可选)组成,各部分之间以文本换行符分隔。HTTP/2 将请求和响应数据分割为更小的帧,并且它们采用二进制编码。

HTTP/2 中,同域名下所有通信都在单个连接上完成,该连接可以承载任意数量的双向数据流。每个数据流都以消息的形式发送,而消息又由一个或多个帧组成。多个帧之间可以乱序发送,根据帧首部的流标识可以重新组装。

(2)多路复用

多路复用,代替原来的序列和阻塞机制。所有就是请求的都是通过一个 TCP连接并发完成。 HTTP 1.x 中,如果想并发多个请求,必须使用多个 TCP 链接,且浏览器为了控制资源,还会对单个域名有 6-8个的TCP链接请求限制,如下图,红色圈出来的请求就因域名链接数已超过限制,而被挂起等待了一段时间。

在 HTTP/2 中,有了二进制分帧之后,HTTP /2 不再依赖 TCP 链接去实现多流并行了,在 HTTP/2中:

  • 同域名下所有通信都在单个连接上完成。
  • 单个连接可以承载任意数量的双向数据流。
  • 数据流以消息的形式发送,而消息又由一个或多个帧组成,多个帧之间可以乱序发送,因为根据帧首部的流标识可以重新组装。

这一特性,使性能有了极大提升:

  • 同个域名只需要占用一个 TCP 连接,消除了因多个 TCP 连接而带来的延时和内存消耗。
  • 单个连接上可以并行交错的请求和响应,之间互不干扰。
  • 在HTTP/2中,每个请求都可以带一个31bit的优先值,0表示最高优先级, 数值越大优先级越低。有了这个优先值,客户端和服务器就可以在处理不同的流时采取不同的策略,以最优的方式发送流、消息和帧。

(3)服务器推送

服务端可以在发送页面HTML时主动推送其它资源,而不用等到浏览器解析到相应位置,发起请求再响应。例如服务端可以主动把JS和CSS文件推送给客户端,而不需要客户端解析HTML时再发送这些请求。

服务端可以主动推送,客户端也有权利选择是否接收。如果服务端推送的资源已经被浏览器缓存过,浏览器可以通过发送RST_STREAM帧来拒收。主动推送也遵守同源策略,服务器不会随便推送第三方资源给客户端。

(4)头部压缩

HTTP 1.1请求的大小变得越来越大,有时甚至会大于TCP窗口的初始大小,因为它们需要等待带着ACK的响应回来以后才能继续被发送。HTTP/2对消息头采用HPACK(专为http/2头部设计的压缩格式)进行压缩传输,能够节省消息头占用的网络的流量。而HTTP/1.x每次请求,都会携带大量冗余头信息,浪费了很多带宽资源。

第三部分:网络层

1. mac和ip怎么转换

ARP协议:

将IP地址通过广播 目标MAC地址是FF-FF-FF-FF-FF-FF 解析目标IP地址的MAC地址
扫描本网段MAC地址。

DHCP协议:

DHCP租约过程就是DHCP客户机动态获取IP地址的过程。

DHCP租约过程分为4步:

  1. 客户机请求IP(客户机发DHCPDISCOVER广播包);

  2. 服务器响应(服务器发DHCPOFFER广播包);

  3. 客户机选择IP(客户机发DHCPREQUEST广播包);

  4. 服务器确定租约(服务器发DHCPACK/DHCPNAK广播包)。

2. IP地址子网划分

二进制 十进制
1 1
10 2
100 4
1000 8
10000 16
100000 32
1000000 64
10000000 128
10000000 128
11000000 192
11100000 224
11110000 240
11111000 248
11111100 252
11111110 254
11111111 255

IP分类
公有地址:
IP分类        缺省掩码
A 1-127      /8
B 128-191        /16
C 192-223      /24
D 224-239      组播地址
E 240-247    保留地址
私有地址:
A:10.0.0.0 - 10.255.255.255
B:  172.16.0.0 - 172.31.255.255
C:  192.168.0.0 - 192.168.255.255

判断合法的主机(IP)地址:
192.168.10.240/24        合法
192.168.10.0/24          不合法,主机位全为0,网络地址
192.168.10.255/24        不合法,主机位全为1,子网广播地址
255.255.255.255              不合法,网络和主机位全为1,全网广播地址
127.x.x.x/8                不合法,本地环回地址
172.16.3.5/24              合法
192.168.5.240/32        合法
224.10.10.10.1              不合法,组播地址
300.2.4.200/24              不合法
  • IP特殊地址
    • 本地环回地址:127.0.0.0 – 127.255.255.255,测试主机TCP/IP协议栈是否安装正确。
    • 本地链路地址:169.254.0.0 – 169.254.255.255,自动地址无法获取时系统自动配置占位。
    • 受限广播地址:255.255.255.255,发往这个地址的数据不能跨越三层设备,但本地网络内所有的主机都可以接收到数据

3. 地址解析协议ARP

4. 交换机和路由器的区别

  1. 路由器可以给你的局域网自动分配IP,虚拟拨号,就像一个交通警察,指挥着你的电脑该往哪走,你自己不用操心那么多了。交换机只是用来分配网络数据的。
  2. 路由器在网络层,路由器根据IP地址寻址,路由器可以处理TCP/IP协议,交换机不可以。
  3. 交换机在中继层,交换机根据MAC地址寻址。路由器可以把一个IP分配给很多个主机使用,这些主机对外只表现出一个IP。交换机可以把很多主机连起来,这些主机对外各有各的IP。
  4. 路由器提供防火墙的服务,交换机不能提供该功能。集线器、交换机都是做端口扩展的,就是扩大局域网(通常都是以太网)的接入点,也就是能让局域网可以连进来更多的电脑。路由器是用来做网间连接,也就是用来连接不同的网络。

交换机是利用物理地址或者说MAC地址来确定转发数据的目的地址。而路由器则是利用不同网络的ID号(即IP地址)来确定数据转发的地址。IP地址是在软件中实现的,描述的是设备所在的网络,有时这些第三层的地址也称为协议地址或者网络地址。MAC地址通常是硬件自带的,由网卡生产商来分配的,而且已经固化到了网卡中去,一般来说是不可更改的。而IP地址则通常由网络管理员或系统自动分配。

路由器和交换机的区别一:交换机是一根网线上网,但是大家上网是分别拨号,各自使用自己的宽带,大家上网没有影响。而路由器比交换机多了一个虚拟拨号功能,通过同一台路由器上网的电脑是共用一个宽带账号,大家上网要相互影响。
路由器和交换机的区别二:交换机工作在中继层,交换机根据MAC地址寻址。路由器工作在网络层,根据IP地址寻址,路由器可以处理TCP/IP协议,而交换机不可以。

路由器和交换机的区别三:交换机可以使连接它的多台电脑组成局域网,如果还有代理服务器的话还可以实现同时上网功能而且局域网所有电脑是共享它的带宽速率的,但是交换机没有路由器的自动识别数据包发送和到达地址的功能。路由器可以自动识别数据包发送和到达的地址,路由器相当于马路上的警察,负责交通疏导和指路的。

路由器和交换机的区别四:举几个例子,路由器是小邮局,就一个地址(IP),负责一个地方的收发(个人电脑,某个服务器,所以你家上网要这个东西),交换机是省里的大邮政中心,负责由一个地址给各个小地方的联系。简单的说路由器专管入网,交换机只管配送,路由路由就是给你找路让你上网的,交换机只负责开门,交换机上面要没有路由你是上不了网的。

路由器和交换机的区别五:路由器提供了防火墙的服务。路由器仅仅转发特定地址的数据包,不传送不支持路由协议的数据包传送和未知目标网络数据包的传送,从而可以防止广播风暴。

5. 子网掩码的作用

内网中192.168.1.199的前三组是网络号,后一组是主机号,子网掩码就是255.255.255.0

首先要说明的是:不是某个IP的网络号和主机号决定子网掩码是什么,而是子网掩码决定了某个IP地址的网络号与主机号是什么,IP地址是要搭配子网掩码使用的。例如上面的子网掩码决定了192.168.1.199的前三段192.168.1是网络号,最后一段199是主机号。

我们再来理解子网掩码的作用,先举个例子,市面上的两个厂家都生产电子秤,每个厂家都坚称他们的秤最准,那你是怎么知道他们的秤到底准不准?很简单,你去找一个 1KG 的国际千克原器,各放到他们的秤上测量,如果秤的测量值是1KG,那这把秤就是准的,子网掩码的作用就相当于这个大家公认的国际千克原器,是我们测量两个IP是否属于同一个网段的一个工具(应该说是让你知道某个IP地址的网络号与主机号分别是什么) 。

如果让你判断一个IP地址:192.168.1.199的网络号和主机号分别是什么?

请问你怎么判断?你凭什么说192.168.1是网络号?199是主机号?有什么根据吗?

但是如果我给你一个IP地址是以下(带子网掩码)形式的:

IP:192.168.1.199

子网掩码:255.255.255.0

那么根据大家公认的规则,你就可以得出这个IP的网络号和主机号了,怎么算呢?

子网掩码的长度和IP地址一样也是一串32位的二进制数字,只不过为人类的可读性和记忆性的方便,通常使用十进制数字来表示,例如把上面的IP地址和子网掩码都转换成相应的二进制就是下面这样的:

                    **十进制**                                                   **二进制**

IP 地址:192.168.1.199 ‐>11000000.10101000.00000001.11000111

子网掩码:255.255.255.0 ‐>11111111.11111111.11111111.00000000

十进制的显示形式是给人看的,二进制的显示形式是给计算机看的。。。

子网掩码的左边是网络位,用二进制数字“1”表示,1的数目等于网络位的长度;右边是主机位,用二进制数字“0”表示,0的数目等于主机位的长度。

例如上面的子网掩码255.255.255.0的 “1”的个数是左边24位,则对应IP地址左边的位数也是24位;

                    **十进制**                                                   **二进制**

IP 地址:192.168.1.199 ‐>11000000.10101000.00000001.11000111

子网掩码:255.255.255.0 ‐>11111111.11111111.11111111.00000000

则这个IP地址的网络号就是11000000.10101000.00000001 ,转换成十进制就是 192.168.1,网掩码255.255.255.0的 “0”的个数是右边8位,则这个IP地址的主机号就是11000111,转换成十进制就是199.

参考资料