# 目录

  * [网卡和路由器](#网卡和路由器)
  * [交换机](#交换机)
  * [以太网](#以太网)
  * [虚拟局域网VLAN](#虚拟局域网vlan)
  * [DHCP协议(动态主机配置协议)](#dhcp协议动态主机配置协议)
  * [ARP协议](#arp协议)
  * [网关和NAT](#网关和nat)
  * [DNS协议和http请求过程](#dns协议和http请求过程)
  * [ICMP](#icmp)
  * [虚拟专用网VPN和内网ip](#虚拟专用网vpn和内网ip)
  * [应用层](#应用层)
    * [http](#http)
    * [http1.0 1.1和2.0](#http10-11和20)
      * [1.0和1.1的主要变化](#10和11的主要变化)
      * [http1.0和http2.0的区别。](#http10和http20的区别。)
    * [get和post](#get和post)
    * [](#)
      * [session和cookie](#session和cookie)
      * [token](#token)
      * [cas单点登录](#cas单点登录)
  * [web安全和https](#web安全和https)
    * [密码加密](#密码加密)
    * [xss跨站脚本攻击](#xss跨站脚本攻击)
    * [跨站点请求伪造csrf](#跨站点请求伪造csrf)
    * [SQL 注入攻击](#sql-注入攻击)
    * [拒绝服务攻击](#拒绝服务攻击)
    * [https](#https)
  * [传输层](#传输层)
    * [UDP报文](#udp报文)
    * [TCP 首部格式](#tcp-首部格式)
    * [三次握手和四次挥手](#三次握手和四次挥手)
    * [半连接syn和洪泛法攻击](#半连接syn和洪泛法攻击)
    * [为什么要三次握手](#为什么要三次握手)
    * [time wait的作用](#time-wait的作用)
  * [可靠传输协议](#可靠传输协议)
    * [tcp的粘包拆包](#tcp的粘包拆包)
  * [网络层](#网络层)
  * [IP 数据报格式](#ip-数据报格式)
  * [某个聚合路由地址划分网络给n台机器，是否符合要求。。](#某个聚合路由地址划分网络给n台机器，是否符合要求。。)
    * [IP 地址编址方式](#ip-地址编址方式)
    * [[](https://github.com/CyC2018/Interview-Notebook/blob/master/notes/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C.md#1-%E5%88%86%E7%B1%BB)1\. 分类](#[]httpsgithubcomcyc2018interview-notebookblobmasternotese8aea1e7ae97e69cbae7bd91e7bb9cmd1-e58886e7b1bb1-分类)
    * [ip分片详谈](#ip分片详谈)
    * [路由选择协议和算法](#路由选择协议和算法)
  * [链路层](#链路层)



---
title: 计算机网络学习总结
date: 2018-07-09 22:32:57
tags:
	- 计算机网络
categories:
	- 后端
	- 技术总结
---
这部分内容主要是基于一些关于计算机网络基础的学习总结，内容不全面，只讲述了其中的一小部分，后续会再补充，如有错误，还请见谅。

<!-- more -->

 计算机网络常见概念

## 网卡和路由器

网卡是一个有mac地址的物理设备，通过mac地址与局域网内的交换机通信，交换机可以识别mac地址。

而单纯的中继器，集线器，双绞线等设备只识别物理层设备。

路由器则工作在3层ip层，必须要有ip才能工作，所以路由器每一个接口都对应一个ip，维护一个可以识别ip的路由表，进行ip数据报转发。

## 交换机
交换机具有自学习能力，学习的是交换表的内容。交换表中存储着 MAC 地址到接口的映射。

## 以太网
以太网是一种星型拓扑结构局域网。

早期使用集线器进行连接，它是一种物理层设备，作用于比特而不是帧，当一个比特到达接口时，集线器重新生成这个比特，并将其能量强度放大，从而扩大网络的传输距离。之后再将这个比特向其它所有接口。特别是，如果集线器同时收到同时从两个不同接口的帧，那么就发生了碰撞。

目前以太网使用交换机替代了集线器，它不会发生碰撞，能根据 MAC 地址进行存储转发。

## 虚拟局域网VLAN
正常情况下，局域网中的链路层广播在整个局域网可达，而vlan可以在物理局域网中划分虚拟局域网，使广播帧只有在vlan当中的主机才能收到。

虚拟局域网可以建立与物理位置无关的逻辑组，只有在同一个虚拟局域网中的成员才会收到链路层广播信息，例如下图中 (A1, A2, A3, A4) 属于一个虚拟局域网，A1 发送的广播会被 A2、A3、A4 收到，而其它站点收不到。

## DHCP协议(动态主机配置协议)

首先DHCP是为了让主机获得一个ip地址，所以主机会发一个0.0.0.0为发送方，255.255.255.255为接收方的ip数据报，也就是广播数据报，并且广播数据包只在局域网中有效，然后链路层解析为数据帧，发送给局域网内的DHCP服务器。

## ARP协议
arp负责把ip地址解析成局域网内的一个mac地址，只在局域网中有效。逆arp则把mac地址解析成ip地址。

网络层实现主机之间的通信，而链路层实现具体每段链路之间的通信。因此在通信过程中，IP 数据报的源地址和目的地址始终不变，而 MAC 地址随着链路的改变而改变。

[![](https://github.com/CyC2018/Interview-Notebook/raw/master/pics/66192382-558b-4b05-a35d-ac4a2b1a9811.jpg)](https://github.com/CyC2018/Interview-Notebook/blob/master/pics/66192382-558b-4b05-a35d-ac4a2b1a9811.jpg)

ARP 实现由 IP 地址得到 MAC 地址。

[![](https://github.com/CyC2018/Interview-Notebook/raw/master/pics/b9d79a5a-e7af-499b-b989-f10483e71b8b.jpg)](https://github.com/CyC2018/Interview-Notebook/blob/master/pics/b9d79a5a-e7af-499b-b989-f10483e71b8b.jpg)

每个主机都有一个 ARP 高速缓存，里面有本局域网上的各主机和路由器的 IP 地址到硬件地址的映射表。

> 如果主机 A 知道主机 B 的 IP 地址，但是 ARP 高速缓存中没有该 IP 地址到 MAC 地址的映射，此时主机 A 通过广播的方式发送 ARP 请求分组，主机 B 收到该请求后会发送 ARP 响应分组给主机 A 告知其 MAC 地址，随后主机 A 向其高速缓存中写入主机 B 的 IP 地址到 MAC 地址的映射。

## 网关和NAT
当需要和外部局域网访问时，需要经过网关服务器以便兼容不同协议栈。局域网内部使用内网ip，经过网关时要转成外网ip，网关会帮你完成改写操作，当收到数据报时，网关又会帮你把ip改为内网ip。这种修改ip隐藏内部网络的方式叫做NAT。

nat穿透的方式是主机和网关服务器协定一个ip地址作为主机服务的ip，所以主机可以通过这个ip和外网交流。

## DNS协议和http请求过程
访问一个域名时，会发送dns报文请求（应用层）给本地的DNS服务器，解析出域名对应的ip，然后三次握手建立连接，（当然TCP数据报由本地局域网经过网关转给外网，再经过多次路由才到达目标主机），然后发送http请求获得响应报文

## ICMP
ICMP 是为了更有效地转发 IP 数据报和提高交付成功的机会。它封装在 IP 数据报中，但是不属于高层协议。

[![](https://github.com/CyC2018/Interview-Notebook/raw/master/pics/e3124763-f75e-46c3-ba82-341e6c98d862.jpg)](https://github.com/CyC2018/Interview-Notebook/blob/master/pics/e3124763-f75e-46c3-ba82-341e6c98d862.jpg)

ICMP 报文分为差错报告报文和询问报文。

[![](https://github.com/CyC2018/Interview-Notebook/raw/master/pics/aa29cc88-7256-4399-8c7f-3cf4a6489559.png)](https://github.com/CyC2018/Interview-Notebook/blob/master/pics/aa29cc88-7256-4399-8c7f-3cf4a6489559.png)


    1. Ping
    Ping 是 ICMP 的一个重要应用，主要用来测试两台主机之间的连通性。
    
    Ping 发送的 IP 数据报封装的是无法交付的 UDP 用户数据报。
    
    2. Traceroute
    Traceroute 是 ICMP 的另一个应用，用来跟踪一个分组从源点到终点的路径，事实上，traceroute也封装着无法交付的udp，和ping类似。。

源主机向目的主机发送一连串的 IP 数据报，每个数据包的ttl时间不同，所以可以跟踪每一跳路由的信息。

==但是因为数据报封装的是无法交付的UDP报文，因此目的主机要向源主机发送 ICMP终点不可达差错报告报文。之后源主机知道了到达目的主机所经过的路由器 IP地址以及到达每个路由器的往返时间。==

## 虚拟专用网VPN和内网ip

由于 IP 地址的紧缺，一个机构能申请到的 IP 地址数往往远小于本机构所拥有的主机数。并且一个机构并不需要把所有的主机接入到外部的互联网中，机构内的计算机可以使用仅在本机构有效的 IP 地址（专用地址）。

有三个专用地址块：

*   10.0.0.0 ~ 10.255.255.255
*   172.16.0.0 ~ 172.31.255.255
*   192.168.0.0 ~ 192.168.255.255

这些ip也称为内网ip，用于局域网间的通信，只能通过网关抵达公网。

[![](https://github.com/CyC2018/Interview-Notebook/raw/master/pics/1556770b-8c01-4681-af10-46f1df69202c.jpg)](https://github.com/CyC2018/Interview-Notebook/blob/master/pics/1556770b-8c01-4681-af10-46f1df69202c.jpg)

使用隧道技术实现vpn。

    原理是；普通的内网ip无法被访问到，一般可以使用nat技术让网关作为中转人，而ip数据报也会改写成网关服务器的地址。
    
    如果想让数据报保留内网地址，并且实现跨公网访问，那么只能通过隧道技术，把内网数据报加密包装在公网ip数据报中，然后通过公网ip抵达对方的专用网络，进行拆包和发送。
    
    为什么vpn能翻墙呢，因为我们通过对vpn服务器的连接，可以将内网ip数据报装在里面，发送给vpn，vpn解析后再发送给真正的服务器。
    
    由于本地网关阻拦了某些网站的请求，所以我们要把这个请求加密封装，然后通过隧道把数据发给一个海外服务器，让他真正完成请求。

## 应用层

应用层的协议主要是http，ftp这类协议，http访问超文本html，而ftp访问文件系统。

### http

通过浏览器可以方便地进行dns解析，建立tcp连接，发送http请求，得到http响应，这些工作都是浏览器完成的。

### http1.0 1.1和2.0

#### 1.0和1.1的主要变化

    1 http1.0经过多年发展，在1.1提出了改进。
    首先是提出了长连接，http请求可以在一次tcp连接中不断发送。
    
    2 然后是http1.1支持只发送header而不发送body。原因是先用header判断能否成功，再发数据，节约带宽，事实上，post请求默认就是这样做的。
    
    3 http1.1的host字段。由于虚拟主机可以支持多个域名，所以一般将域名解析后得到host。

#### http1.0和http2.0的区别。

    http2.0变化巨大。
    
    1 http支持多路复用，同一个连接可以并发处理多个请求，方法是把http数据包拆为多个帧，并发有序的发送，根据序号在另一端进行重组，而不需要一个个http请求顺序到达。
    
    2 http2.0支持服务端推送，就是服务端在http请求到达后，除了返回数据之外，还推送了额外的内容给客户端。
    
    3HTTP2.0压缩了请求头，同时基本单位是二进制帧流，这样的数据占用空间更少。
    
    4http2.0只适用于https场景，因为其在http和tcp中间加了一层ssl层。

### get和post

    get和post本质都是http请求，只不过对他们的作用做了界定和适配，并且让他们适应各自的场景。
    
    1本质区别是get只是一次http请求，post先发请求体再发请求体，实际上是两次请求
    
    2表面区别：
    
    get可以cache而post不能，因为浏览器是这么安排的
    
    一般设计get是幂等的而post不是
    
    get的参数放在url传递，而post放在请求体里，因为get没有请求体。
    所以get请求不安全，并且有长度限制（url不能太长），而post几乎没有限制，请求体可以很大。

### 


#### session和cookie

并且浏览器还维护了cookie以便记录用于对网站的一些信息，下次请求时在http报文中带上这些数据，服务器接收以后根据cookie中的sessionid获取对应的session即可

#### token

session一般维护在内存中，有时候也会持久化到数据库，但是如果session由单点维护可能出现宕机等情况，于是一般会采用分布式的方案。


    session存放的几种方案。
    0 存在内存中。用sessionid标识用户。
    这样的session十分依赖于cookie。如果浏览器禁用了cookie则session无用武之地。
    
    当然也可以把内容存在数据库里，缺点是数据库访问压力较大。
    
    1有做法会将session内容存在cookie中，但前提是经过了加密，然后下次服务器对其进行解密，但是这样浏览器需要维护太多内容了。
    
    2当用户登录或者执行某些操作，则使用用户的一部分字段信息进行加密算法得到一串字符串成为token，用于唯一标识用户，或者是某些操作，比如登录，支付，服务端生成该token返回给用户，用户提交请求时必须带上这个token，就可以确认用户信息以及操作是否合法了。
    
    这样我们不需要存session，只需要在想得到用户信息时解密token即可。
    
    token还有一个好处就是可以在移动端和pc端兼容，因为移动端不支持cookie。
    
    3token和oauth。经常有第三方授权登录的例子，本质就是使用token。首先我们打开授权登录页，登陆后服务端返回token，我们提交第三方的请求时，带上这个token，第三方不知道他是啥意思，并且token过段时间就过期了。

#### cas单点登录

单点登录是为了多个平台之间公用一个授权系统，做法是，所有登录都要指向统一登录服务，登陆成功以后在认证中心建立session，并且得到ticket，然后重定向页面，此时页面也会向认证中心确认ticket是否合法，然后就可以访问其他系统的页面了。

从而访问其他系统时，由于已经有了认证中心的cookie，所以直接带上ticket访问即可。

每次访问新系统时需要在认证中心注册session，然后单点退出时再把这些session退出，才能实现用户登出。

## web安全和https

### 密码加密

MD5等加密方法可以用来对密码进行加密。一般还会加盐

### xss跨站脚本攻击

利用有输入功能网站的输入框来注入JavaScript脚本代码，用户访问该页面时会自动执行某些脚本代码，导致cookie等个人信息泄露，可能会被转发到其他网站。

解决办法是对输入进行检验，利用一个些工具类就可以做到。

### 跨站点请求伪造csrf
首先用户访问了一个网站并登陆，会把cookie保留在浏览器，
然后某些网站用一些隐性链接诱导用户点击，点击时发送请求会携带浏览器中的cookie，比如支付宝的账号密码，通过该cookie再去伪造一个支付宝支付请求，达到伪造请求的目的。 

解决这个问题的办法就是禁止js请求跨域名。但是他为ajax提供了特殊定制。

### SQL 注入攻击
1. 概念
服务器上的数据库运行非法的 SQL 语句，主要通过拼接来完成。

3. 防范手段
（一）使用参数化查询

以下以 Java 中的 PreparedStatement 为例，它是预先编译的 SQL 语句，可以传入适当参数并且多次执行。由于没有拼接的过程，因此可以防止 SQL 注入的发生。

（二）单引号转换

将传入的参数中的单引号转换为连续两个单引号，PHP 中的 Magic quote 可以完成这个功能。

### 拒绝服务攻击
拒绝服务攻击（denial-of-service attack，DoS），亦称洪水攻击，其目的在于使目标电脑的网络或系统资源耗尽，使服务暂时中断或停止，导致其正常用户无法访问。

分布式拒绝服务攻击（distributed denial-of-service attack，DDoS），指攻击者使用网络上两个或以上被攻陷的电脑作为“僵尸”向特定的目标发动“拒绝服务”式攻击。

DDoS攻击通过大量合法的请求占用大量网络资源，以达到瘫痪网络的目的。 

这种攻击方式可分为以下几种：

    通过使网络过载来干扰甚至阻断正常的网络通讯；
    通过向服务器提交大量请求，使服务器超负荷；
    阻断某一用户访问服务器；
    阻断某服务与特定系统或个人的通讯。

攻击现象

    被攻击主机上有大量等待的TCP连接；
    网络中充斥着大量的无用的数据包；
    源地址为假 制造高流量无用数据，造成网络拥塞，使受害主机无法正常和外界通讯；
    利用受害主机提供的传输协议上的缺陷反复高速的发出特定的服务请求，使主机无法处理所有正常请求；
    严重时会造成系统死机。

总体来说，对DoS和DDoS的防范主要从下面几个方面考虑：

    尽可能对系统加载最新补丁，并采取有效的合规性配置，降低漏洞利用风险；
    
    采取合适的安全域划分，配置防火墙、入侵检测和防范系统，减缓攻击。
    
    采用分布式组网、负载均衡、提升系统容量等可靠性措施，增强总体服务能力。
### https

https博大精深，首先先来看看他的基础知识

    1对称加密和非对称加密
    
    对称加密两方使用同一把密钥加密和解密，传输密钥时如果丢失就会被破解。
    
    2非对称加密两方各有一把私钥，而公钥公开，A用私钥加密，把公钥和数据传给B，B用公钥解密。同理，B用私钥对数据进行加密，返回给A，A也用公钥进行解密。
    
    3非对称加密只要私钥不丢就很安全，但是效率比较低，所以一般使用非对称加密传输对称加密的密钥，使用对称加密完成数据传输。
    
    4数字签名，为了避免数据在传输过程中被替换，比如黑客修改了你的报文内容，但是你并不知道，所以我们让发送端做一个数字签名，把数据的摘要消息进行一个加密，比如MD5，得到一个签名，和数据一起发送。然后接收端把数据摘要进行md5加密，如果和签名一样，则说明数据确实是真的。
    
    5数字证书，对称加密中，双方使用公钥进行解密。虽然数字签名可以保证数据不被替换，但是数据是由公钥加密的，如果公钥也被替换，则仍然可以伪造数据，因为用户不知道对方提供的公钥其实是假的。
    
    所以为了保证发送方的公钥是真的，CA证书机构会负责颁发一个证书，里面的公钥保证是真的，用户请求服务器时，服务器将证书发给用户，这个证书是经由系统内置证书的备案的。


​    
​    
    6 https过程
    
    用户发送请求，服务器返回一个数字证书。
    
    用户在浏览器端生成一个随机数，使用证书中的公钥加密，发送给服务端。
    
    服务端使用公钥解密该密文，得到随机数。
    
    往后两者使用该随机数作为公钥进行对称加密。


    番外：关于公钥加密私钥解密与私钥加密公钥解密说明
    第一种是签名,使用私钥加密,公钥解密,用于让所有公钥所有者验证私钥所有者的身份并且用来防止私钥所有者发布的内容被篡改.但是不用来保证内容不被他人获得. 
    
    第二种是加密,用公钥加密,私钥解密,用于向公钥所有者发布信息,这个信息可能被他人篡改,但是无法被他人获得.搜索 


## 传输层

    UDP 和 TCP 的特点
    用户数据报协议 UDP（User Datagram Protocol）是无连接的，尽最大可能交付，没有拥塞控制，面向报文（对于应用程序传下来的报文不合并也不拆分，只是添加 UDP 首部），支持一对一、一对多、多对一和多对多的交互通信。
    
    传输控制协议 TCP（Transmission Control Protocol）是面向连接的，提供可靠交付，有流量控制，拥塞控制，提供全双工通信，面向字节流（把应用层传下来的报文看成字节流，把字节流组织成大小不等的数据块），每一条 TCP 连接只能是点对点的（一对一）。

TCP是传输层最重要的协议。
> 
> 由于网络层只提供最大交付的服务，尽可能地完成路由转发，以及把链路层报文传送给任意一台主机。他做的工作很专注，所以不会提供其他的可靠性保证。
> 
> 但是真实网络环境下随时会发生丢包，乱序，数据内容出错等情况，这些情况必须得到处理，于是我们使用传输层tcp来解决这些问题。

### UDP报文

伪首部的意义：伪首部并非TCP&UDP数据报中实际的有效成分。伪首部是一个虚拟的数据结构，其中的信息是从数据报所在IP分组头的分组头中提取的，既不向下传送也不向上递交，而仅仅是为计算校验和。

![image](https://github.com/CyC2018/Interview-Notebook/raw/master/pics/d4c3a4a1-0846-46ec-9cc3-eaddfca71254.jpg)

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

### TCP 首部格式

[![](https://github.com/CyC2018/Interview-Notebook/raw/master/pics/55dc4e84-573d-4c13-a765-52ed1dd251f9.png)](https://github.com/CyC2018/Interview-Notebook/blob/master/pics/55dc4e84-573d-4c13-a765-52ed1dd251f9.png)

*   **序号** ：用于对字节流进行编号，例如序号为 301，表示第一个字节的编号为 301，如果携带的数据长度为 100 字节，那么下一个报文段的序号应为 401。

*   **确认号** ：期望收到的下一个报文段的序号。例如 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 时，表示此报文段的发送方的数据已发送完毕，并要求释放连接。

*   **窗口** ：窗口值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制，是因为接收方的数据缓存空间是有限的。
*  

###     三次握手和四次挥手
    为了保证tcp的可靠传输，需要建立起一条通路，也就是所谓连接。这条通路必须保证有效并且能正确结束。

[![](https://github.com/CyC2018/Interview-Notebook/raw/master/pics/e92d0ebc-7d46-413b-aec1-34a39602f787.png)](https://github.com/CyC2018/Interview-Notebook/blob/master/pics/e92d0ebc-7d46-413b-aec1-34a39602f787.png)


​    
    三次握手
    
    1 首先客户端发送连接请求syn，携带随机数x。
    2 服务端返回请求ack，x + 1,说明服务端对x进行了回复。
    3 客户端返回请求ack，y，说明接受到了信息并且开始传输数据，起始数据为y。
    
    客户端状态时syn_send和establish
    服务端则是从listen到syn_rcvd，再到establish

[![](https://github.com/CyC2018/Interview-Notebook/raw/master/pics/f87afe72-c2df-4c12-ac03-9b8d581a8af8.jpg)](https://github.com/CyC2018/Interview-Notebook/blob/master/pics/f87afe72-c2df-4c12-ac03-9b8d581a8af8.jpg)

    四次挥手
    
    1 首先客户端请求断开连接，发送fin请求，服务端返回fin的ack，继续处理断开前需要处理完的数据。
    
    2 过了一会，服务端处理完数据发送给客户端ack，表明已经关闭，客户端最后再发一个ack给服务端，如果服务端已关闭则无反应，客户端经过两个ttl后挥手完毕，确认服务端断开。这两个ttl成为time wait状态，用于确定服务端真的关闭。
    
    3 客户端发完fin后的状态从establish变为fin1——wait，服务端发完ack后的状态从establish变为closewait。
    
    4 客户端收到第一个ack后进入fin_2wait状态，服务端过了一会发送last——ack给客户端，说明关闭好了，客户端收到ack后进入timewait，然后发送ack。双方都closed。

### 半连接syn和洪泛法攻击

黑客开启大量的syn请求而不发送ack，服务端开启半连接等待ack，直到资源耗尽，所以必须检测来访ip
### 为什么要三次握手

三次握手的原因

第三次握手是为了防止失效的连接请求到达服务器，让服务器错误打开连接。

也就是说，如果只有两次握手，服务端返回ack后直接通信，那么如果客户端因为网络问题没有收到ack，可能会再次请求连接，但时服务端不知道这其实是同一个请求，于是又打开了一个连接，相当于维护了很多的无用连接。
### time wait的作用

1 需要服务端可靠地终止连接，如果处于time_wait客户端发给服务端的ack报文丢失，则服务端会再发一次fin，此时客户端不应该关闭。

2 保证迟来的tcp报文有时间被丢弃，因为2msl里超时抵达的报文都会被丢弃。

## 可靠传输协议

TCP协议有三个重要属性。

    可靠传输，主要通过有序接收，确认后发送，以及超时重传来实现，并且使用分片来提高发送效率，通过检验和避免错误。
    
    流量控制，主要通过窗口限制接收和发送速率。
    
    拥塞控制，主要通过不同拥塞状态的算法来处理拥塞，一开始发的比较慢，然后指数增加，当丢包时再降低速度，重新开始第一阶段，避免拥塞。

总结以下就是几个特点：

TCP 可靠传输

    TCP 使用超时重传来实现可靠传输：
    
    1 如果一个已经发送的报文段在超时时间内没有收到确认，那么就重传这个报文段。


​    
    2 滑动窗口可以连续发送多个数据再统一进行确认。
    
       因为发送端希望在收到确认前，继续发送其它报文段。比如说在收到0号报文的确认前还发出了1-3号的报文，这样提高了信道的利用率。
       
    3 滑动窗口只重传丢失的数据报
       
    但可以想想，0-4发出去后可能要重传，所以需要一个缓冲区维护这些报文，所以就有了窗口。
    
    4每当完成一个确认窗口往前滑动一格，可以传新的一个数据，因此可以顺序发送顺序确认

TCP 流量控制

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

TCP 拥塞控制

    如果网络出现拥塞，分组将会丢失，此时发送方会继续重传，从而导致网络拥塞程度更高。因此当出现拥塞时，应当控制发送方的速率。这一点和流量控制很像，但是出发点不同。流量控制是为了让接收方能来得及接受，而拥塞控制是为了降低整个网络的拥塞程度。
    
    TCP 主要通过四种算法来进行拥塞控制：慢开始、拥塞避免、快重传、快恢复。
    
    一般刚开始时慢开始，然后拥塞避免，出现个别丢包时（连续三个包序号不对），
    
    则执行快重传，然后进入快恢复阶段，接着继续拥塞避免。如果发生多次超时也就是拥塞时，直接进入慢开始。
>     
>这种情况下，只是丢失个别报文段，而不是网络拥塞，因此执行快恢复，令 ssthresh = cwnd/2 ，cwnd = ssthresh，注意到此时直接进入拥塞避免。慢开始和快恢复的快慢指的是 cwnd 的设定值，而不是 cwnd 的增长速率。慢开始 cwnd 设定为 1，而快恢复 cwnd 设定为 ssthresh。

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

滑动窗口协议综合实现了上述这一些内容：

为什么要使用滑动窗口，因为滑动窗口可以实现可靠传输，流量控制和拥塞控制（拥塞控制用的是拥塞窗口变量）

### tcp的粘包拆包

tcp报文是流式的数据，没有标识数据结束，只有序号等字段，tcp协议自动完成数据报的切分。由于tcp使用缓冲区发送，又没有标识结束，当缓冲区的数据没清空又有新数据进来，就会发生粘包，如果数据太大存装不下，就会被拆包。

## 网络层

## IP 数据报格式

[![](https://github.com/CyC2018/Interview-Notebook/raw/master/pics/85c05fb1-5546-4c50-9221-21f231cdc8c5.jpg)](https://github.com/CyC2018/Interview-Notebook/blob/master/pics/85c05fb1-5546-4c50-9221-21f231cdc8c5.jpg)

*   **版本** : 有 4（IPv4）和 6（IPv6）两个值；

*   **首部长度** : 占 4 位，因此最大值为 15。

*   **总长度** : 包括首部长度和数据部分长度。

*   **生存时间** ：TTL，它的存在是为了防止无法交付的数据报在互联网中不断兜圈子。以路由器跳数为单位，当 TTL 为 0 时就丢弃数据报。

==*   **协议** ：指出携带的数据应该上交给哪个协议进行处理，例如 ICMP、TCP、UDP 等。==

*   **首部检验和** ：因为数据报每经过一个路由器，都要重新计算检验和，因此检验和不包含数据部分可以减少计算的工作量。


*   **片偏移** : 和标识符一起，用于发生分片的情况。片偏移的单位为 8 字节。

[![](https://github.com/CyC2018/Interview-Notebook/raw/master/pics/23ba890e-e11c-45e2-a20c-64d217f83430.png)](https://github.com/CyC2018/Interview-Notebook/blob/master/pics/23ba890e-e11c-45e2-a20c-64d217f83430.png)

总结：

    ip层只保证尽最大努力交付，他所承载的一切都是对路由，转发，已经网络传输最友好的设计。
    
    路由器负责记录路由表和转发ip数据报，路由表记录着ip地址和下一跳路由的端口的对应关系。
    
    由于路由聚合的缘故，一般用170.177.233.0/24就可以标识好几个网络了。
    
    以前会使用A，B，C类地址，和子网，现在直接使用地址聚合，前24位是网络号，后面8位是主机号。
    
    ## 某个聚合路由地址划分网络给n台机器，是否符合要求。。
    
    要看这个网络中的主机号能否达到n个。

### IP 地址编址方式

IP 地址的编址方式经历了三个历史阶段：

*   分类
*   子网划分
*   无分类

### 分类

由两部分组成，网络号和主机号，其中不同分类具有不同的网络号长度，并且是固定的。

IP 地址 ::= {< 网络号 >, < 主机号 >}

[![](https://github.com/CyC2018/Interview-Notebook/raw/master/pics/cbf50eb8-22b4-4528-a2e7-d187143d57f7.png)](https://github.com/CyC2018/Interview-Notebook/blob/master/pics/cbf50eb8-22b4-4528-a2e7-d187143d57f7.png)  

2. 子网划分


    通过在主机号字段中拿一部分作为子网号，把两级 IP 地址划分为三级 IP 地址。注意，外部网络看不到子网的存在。
    
    IP 地址 ::= {< 网络号 >, < 子网号 >, < 主机号 >}
    
    要使用子网，必须配置子网掩码。一个 B 类地址的默认子网掩码为 255.255.0.0，如果 B 类地址的子网占两个比特，那么子网掩码为 11111111 11111111 11000000 00000000，也就是 255.255.192.0。

3. 无分类


    无分类编址 CIDR 消除了传统 A 类、B 类和 C 类地址以及划分子网的概念，使用网络前缀和主机号来对 IP 地址进行编码，网络前缀的长度可以根据需要变化。
    
    IP 地址 ::= {< 网络前缀号 >, < 主机号 >}
    
    CIDR 的记法上采用在 IP 地址后面加上网络前缀长度的方法，例如 128.14.35.7/20 表示前 20 位为网络前缀。
    
    CIDR 的地址掩码可以继续称为子网掩码，子网掩码首 1 长度为网络前缀的长度。

一个 CIDR 地址块中有很多地址，一个 CIDR 表示的网络就可以表示原来的很多个网络，并且在路由表中只需要一个路由就可以代替原来的多个路由，减少了路由表项的数量。

把这种通过使用网络前缀来减少路由表项的方式称为路由聚合，也称为 构成超网 。

在路由表中的项目由“网络前缀”和“下一跳地址”组成，在查找时可能会得到不止一个匹配结果，应当采用最长前缀匹配来确定应该匹配哪一个。

总结
    
    使用分类法的ip必须标识是哪一类地址，比较麻烦，而且一旦设置为某类地址它就只能使用那一部分地址空间了。
    
    使用子网掩码可以避免使用分类并且更灵活地决定网络号和主机号的划分。但是需要配置子网掩码，比较复杂。
    
    CIDR 138.1.2.11/24
    使用CIDR避免了子网划分，直接使用后n位作为网络号，简化了子网的配置（实际上用n代替了子网掩码）。并且在路由器中可以使用地址聚合，一个ip可以聚合多个网络号。

### ip分片详谈

在TCP/IP分层中，数据链路层用MTU（Maximum Transmission Unit，最大传输单元）来限制所能传输的数据包大小，MTU是指一次传送的数据最大长度，不包括数据链路层数据帧的帧头，如以太网的MTU为1500字节，实际上数据帧的最大长度为1512字节，其中以太网数据帧的帧头为12字节。

当发送的IP数据报的大小超过了MTU时，IP层就需要对数据进行分片，否则数据将无法发送成功。

IP分片的实现
    
> IP分片发生在IP层，不仅源端主机会进行分片，中间的路由器也有可能分片，因为不同的网络的MTU是不一样的，如果传输路径上的某个网络的MTU比源端网络的MTU要小，路由器就可能对IP数据报再次进行分片。而分片数据的重组只会发生在目的端的IP层。

==避免IP分片==
> 在网络编程中，我们要避免出现IP分片，那么为什么要避免呢？原因是IP层是没有超时重传机制的，如果IP层对一个数据包进行了分片，只要有一个分片丢失了，只能依赖于传输层进行重传，结果是所有的分片都要重传一遍，这个代价有点大。由此可见，IP分片会大大降低传输层传送数据的成功率，所以我们要避免IP分片。
>         

    对于UDP包，我们需要在应用层去限制每个包的大小，一般不要超过1472字节，即以太网MTU（1500）—UDP首部（8）—IP首部（20）。
    
    对于TCP数据，应用层就不需要考虑这个问题了，因为传输层已经帮我们做了。

在建立连接的三次握手的过程中，连接双方会相互通告MSS（Maximum Segment =Size，最大报文段长度），MSS一般是MTU—IP首部（20）—TCP首部（20），每次发送的TCP数据都不会超过双方MSS的最小值，所以就保证了IP数据报不会超过MTU，避免了IP分片。

3. 外部网关协议 BGP


    BGP（Border Gateway Protocol，边界网关协议）
    
    AS 之间的路由选择很困难，主要是因为互联网规模很大。并且各个 AS 内部使用不同的路由选择协议，就无法准确定义路径的度量。并且 AS 之间的路由选择必须考虑有关的策略，比如有些 AS 不愿意让其它 AS 经过。
    
    BGP 只能寻找一条比较好的路由，而不是最佳路由。
    
    每个 AS 都必须配置 BGP 发言人，通过在两个相邻 BGP 发言人之间建立 TCP 连接来交换路由信息。

### 路由选择协议和算法
> 
> 路由选择协议
> 路由选择协议都是自适应的，能随着网络通信量和拓扑结构的变化而自适应地进行调整。
> 
> 互联网可以划分为许多较小的自治系统 AS，一个 AS 可以使用一种和别的 AS 不同的路由选择协议。
> 
> 可以把路由选择协议划分为两大类：
> 
> 自治系统内部的路由选择：RIP 和 OSPF
> 自治系统间的路由选择：BGP


总结：

    1. 内部网关协议 RIP
    RIP 是一种基于距离向量的路由选择协议。距离是指跳数，直接相连的路由器跳数为 1，跳数最多为 15，超过 15 表示不可达。
    
    RIP 按固定的时间间隔仅和相邻路由器交换自己的路由表，经过若干次交换之后，所有路由器最终会知道到达本自治系统中任何一个网络的最短距离和下一跳路由器地址。
    
    2. 内部网关协议 OSPF
    开放最短路径优先 OSPF，是为了克服 RIP 的缺点而开发出来的。
    
    开放表示 OSPF 不受某一家厂商控制，而是公开发表的；最短路径优先表示使用了 Dijkstra 提出的最短路径算法 SPF。

OSPF 具有以下特点：
    
    计算出最短路径，然后向本自治系统中的所有路由器发送信息，这种方法是洪泛法。
    
    发送的信息就是与相邻路由器的链路状态，链路状态包括与哪些路由器相连以及链路的度量，度量用费用、距离、时延、带宽等来表示。
    
    变化时，路由器才会发送信息。
        
    所有路由器都具有全网的拓扑结构图，并且是一致的。相比于 RIP，OSPF 的更新过程收敛的很快。

总结：

    AS是一个自治域，一般是指相似度很大公用一个协议的路由器族，比如同一个运营商的网络。
    
    因特网中AS之间的路由选择协议是BGP。
    
    AS内的路由选择协议有RIP和OSPF。
    
    RIP两两交换，最后大家都同步。
    
    OSPF找到最短路径。告诉大家。

## 链路层
链路层最主要是指局域网内的网络交互了，使用mac地址通过交换机进行通信，其中用得最多的局域网协议就是以太网。

链路层使用MTU表示最大传输帧长度，报文长度不能超过MTU,否则会进行分片，比如比较大的IP数据报就会被分片，为了避免被分片。一般要控制IP报文长度。

广播：

要理解什么是广播风暴，就必须先理解网络通信技术。 网络上的一个节点，它发送一个数据帧或包，被传输到由广播域定义的本地网段上的每个节点就是广播。

> 网络广播分为第2层广播和第3层广播。第2层广播也称硬件广播，用于在局域网内向所有的结点发送数据，通常不会穿过局域网的边界（路由器），除非它变成一个单播。广播将是一个二进制的全1或者十六进制全F的地址。而第3层广播用于在这个网络内向所有的结点发送数据。

帧的传输方式，即单播帧（Unicast Frame）、多播帧（Multicast Frame）和广播帧（Broadcast Frame）。

    1、单播帧
    单播帧也称“点对点”通信。此时帧的接收和传递只在两个节点之间进行，帧的目的MAC地址就是对方的MAC地址，网络设备（指交换机和路由器）根据帧中的目的MAC地址，将帧转发出去。
    
    2、多播帧
    多播帧可以理解为一个人向多个人（但不是在场的所有人）说话，这样能够提高通话的效率。多播占网络中的比重并不多，主要应用于网络设备内部通信、网上视频会议、网上视频点播等。
    
    3、广播帧
    广播帧可以理解为一个人对在场的所有人说话，这样做的好处是通话效率高，信息一下子就可以传递到全体。在广播帧中，帧头中的目的MAC地址是“FF.FF.FF.FF.FF.FF”，代表网络上所有主机网卡的MAC地址。
    
    广播帧在网络中是必不可少的，如客户机通过DHCP自动获得IP地址的过程就是通过广播帧来实现的。而且，由于设备之间也需要相互通信，因此在网络中即使没有用户人为地发送广播帧，网络上也会出现一定数量的广播帧。
    
    同单播和多播相比，广播几乎占用了子网内网络的所有带宽。网络中不能长时间出现大量的广播帧，否则就会出现所谓的“广播风暴”（每秒的广播帧数在1000以上）。拿开会打一个比方，在会场上只能有一个人发言，如果所有人都同时发言的话，会场上就会乱成一锅粥。广播风暴就是网络长时间被大量的广播数据包所占用，使正常的点对点通信无法正常进行，其外在表现为网络速度奇慢无比。出现广播风暴的原因有很多，一块故障网卡就可能长时间地在网络上发送广播包而导致广播风暴。
    
    使用路由器或三层交换机能够实现在不同子网间隔离广播风暴的作用。当路由器或三层交换机收到广播帧时并不处理它，使它无法再传递到其他子网中，从而达到隔离广播风暴的目的。因此在由几百台甚至上千台电脑构成的大中型局域网中，为了隔离广播风暴，都要进行子网划分。
    使用vlan完全可以隔离广播风暴。

> 在交换以太网上运行TCP/IP环境下：
> 二层广播是在数据链路层的广播，它 的广播范围是二层交换机连接的所有端口；二层广播不能通过路由器。
> 
> 三层广播就是在网络层的广播，它的范围是同一IP子网内的设备，子网广播也不能通过路由器。
> 
> 第三层的数据必须通过第二层的封装再发送，所以三层广播必然通过二层广播来实现。
> 
> 设想在同一台二层交换机上连接2个ip子网的设备，所有的设备都可以接收到二层广播，但三层广播只对本子网设备有效，非本子网的设备也会接收到广播包，但会被丢弃。

广播风暴（broadcast storm）

简单的讲是指当广播数据充斥网络无法处理，并占用大量网络带宽，导致正常业务不能运行，甚至彻底瘫痪，这就发生了“广播风暴”

。一个数据帧或包被传输到本地网段 （由广播域定义）上的每个节点就是广播；由于网络拓扑的设计和连接问题，或其他原因导致广播在网段内大量复制，传播数据帧，导致网络性能下降，甚至网络瘫痪，这就是广播风暴。

要避免广播风暴，可以采用恰当划分VLAN、缩小广播域、隔离广播风暴，还可在千兆以太网口上启用广播风暴控制，最大限度地避免网络再次陷入瘫痪。


