├── 1.ip掩码.md ├── 10.网络安全.md ├── 11.HTTPS.md ├── 12.HTTP协议的升级改进.md ├── 13.其他协议和补充知识.md ├── 2.路由和其他概念.md ├── 3.物理层和数据链路层.md ├── 4.网络层.md ├── 5.传输层.md ├── 6.TCP--连接管理.md ├── 7.应用层1.md ├── 8.HTTP(上).md ├── 9.HTTP(下).md ├── images ├── ARP广播1.jpg ├── A类地址1.jpg ├── B类地址1.jpg ├── C类地址1.jpg ├── DHCP1.jpg ├── DNS1.jpg ├── DNS2.jpg ├── DNS3.jpg ├── D,E类地址.jpg ├── HTTP1.jpg ├── HTTP1.png ├── HTTP10.jpg ├── HTTP10.png ├── HTTP11.jpg ├── HTTP11.png ├── HTTP12.jpg ├── HTTP12.png ├── HTTP13.jpg ├── HTTP13.png ├── HTTP14.jpg ├── HTTP14.png ├── HTTP15.jpg ├── HTTP16.jpg ├── HTTP17.jpg ├── HTTP18.jpg ├── HTTP19.jpg ├── HTTP2.jpg ├── HTTP2.png ├── HTTP20.jpg ├── HTTP21.jpg ├── HTTP22.jpg ├── HTTP23.jpg ├── HTTP24.jpg ├── HTTP25.jpg ├── HTTP26.jpg ├── HTTP27.jpg ├── HTTP28.jpg ├── HTTP29.jpg ├── HTTP3.jpg ├── HTTP3.png ├── HTTP4.jpg ├── HTTP4.png ├── HTTP5.jpg ├── HTTP5.png ├── HTTP6.jpg ├── HTTP6.png ├── HTTP7.jpg ├── HTTP7.png ├── HTTP8.jpg ├── HTTP8.png ├── HTTP9.jpg ├── HTTP9.png ├── HTTPS1.jpg ├── HTTPS1.png ├── HTTPS10.jpg ├── HTTPS11.jpg ├── HTTPS12.jpg ├── HTTPS13.jpg ├── HTTPS14.jpg ├── HTTPS15.jpg ├── HTTPS16.jpg ├── HTTPS17.jpg ├── HTTPS18.jpg ├── HTTPS19.jpg ├── HTTPS2.jpg ├── HTTPS2.png ├── HTTPS20.jpg ├── HTTPS21.jpg ├── HTTPS22.jpg ├── HTTPS23.jpg ├── HTTPS24.jpg ├── HTTPS25.jpg ├── HTTPS26.jpg ├── HTTPS27.jpg ├── HTTPS28.jpg ├── HTTPS3.jpg ├── HTTPS4.jpg ├── HTTPS5.jpg ├── HTTPS6.jpg ├── HTTPS7.jpg ├── HTTPS8.jpg ├── HTTPS9.jpg ├── IP地址1.jpg ├── IP地址2.jpg ├── IP地址分类1.jpg ├── MAC地址1.jpg ├── TCP01_序号_确认号.png ├── TCP02_流量控制.png ├── TCP协议1.jpg ├── TCP协议10.jpg ├── TCP协议11.jpg ├── TCP协议12.jpg ├── TCP协议13.jpg ├── TCP协议14.jpg ├── TCP协议14.png ├── TCP协议15.jpg ├── TCP协议16.jpg ├── TCP协议17.jpg ├── TCP协议18.jpg ├── TCP协议19.jpg ├── TCP协议2.jpg ├── TCP协议20.jpg ├── TCP协议21.jpg ├── TCP协议22.jpg ├── TCP协议23.jpg ├── TCP协议24.jpg ├── TCP协议25.jpg ├── TCP协议26.jpg ├── TCP协议27.jpg ├── TCP协议28.jpg ├── TCP协议29.jpg ├── TCP协议3.jpg ├── TCP协议30.jpg ├── TCP协议31.jpg ├── TCP协议32.jpg ├── TCP协议33.jpg ├── TCP协议34.jpg ├── TCP协议4.jpg ├── TCP协议5.jpg ├── TCP协议6.jpg ├── TCP协议7.jpg ├── TCP协议8.jpg ├── TCP协议9.jpg ├── TCP连接管理1.png ├── TCP连接管理2.png ├── TCP连接管理3.png ├── TCP连接管理4.png ├── TCP连接管理5.png ├── TCP连接管理6.png ├── TCP连接管理7.png ├── TCP连接管理8.png ├── TCP连接管理9.png ├── image-20210321221611886.png ├── ping广播地址1.jpg ├── 以太网1.jpg ├── 以太网2.jpg ├── 以太网3.jpg ├── 以太网4.jpg ├── 以太网5.jpg ├── 以太网6.jpg ├── 以太网7.jpg ├── 以太网8.jpg ├── 以太网9.jpg ├── 传输层1.jpg ├── 传输层2.jpg ├── 传输层3.jpg ├── 传输层4.jpg ├── 传输层5.jpg ├── 传输层6.jpg ├── 传输层7.jpg ├── 传输层8.jpg ├── 其他协议1.jpg ├── 其他协议10.jpg ├── 其他协议11.jpg ├── 其他协议12.jpg ├── 其他协议13.jpg ├── 其他协议2.jpg ├── 其他协议3.jpg ├── 其他协议4.jpg ├── 其他协议5.jpg ├── 其他协议6.jpg ├── 其他协议7.jpg ├── 其他协议8.jpg ├── 其他协议9.jpg ├── 域名1.jpg ├── 域名2.jpg ├── 域名3.jpg ├── 子网划分1.jpg ├── 子网掩码CIDR表示.jpg ├── 思考1.jpg ├── 思考2-1.jpg ├── 思考2.jpg ├── 思考3.jpg ├── 思考4.jpg ├── 查看路由表1.jpg ├── 第一次丢包1.jpg ├── 第一次丢包2.jpg ├── 第一次丢包3.jpg ├── 第一次丢包4.jpg ├── 第一次丢包5.jpg ├── 第一次丢包6.jpg ├── 第一次丢包7.jpg ├── 等长划分1.jpg ├── 等长子网划分2.jpg ├── 网段合并规律1.jpg ├── 网络安全1.jpg ├── 网络安全1.png ├── 网络安全10.jpg ├── 网络安全11.jpg ├── 网络安全12.jpg ├── 网络安全13.jpg ├── 网络安全14.jpg ├── 网络安全15.jpg ├── 网络安全2.jpg ├── 网络安全2.png ├── 网络安全3.jpg ├── 网络安全3.png ├── 网络安全4.jpg ├── 网络安全5.jpg ├── 网络安全6.jpg ├── 网络安全7.jpg ├── 网络安全8.jpg ├── 网络安全9.jpg ├── 网络层1.jpg ├── 网络层10.jpg ├── 网络层11.jpg ├── 网络层2.jpg ├── 网络层3.jpg ├── 网络层4.jpg ├── 网络层5.jpg ├── 网络层6.jpg ├── 网络层7.jpg ├── 网络层8.jpg ├── 网络层9.jpg ├── 网络模型1.jpg ├── 网络模型10.jpg ├── 网络模型11jpg.jpg ├── 网络模型2.jpg ├── 网络模型3.jpg ├── 网络模型4.jpg ├── 网络模型5.jpg ├── 网络模型6.jpg ├── 网络模型7.jpg ├── 网络模型8.jpg ├── 网络模型9.jpg ├── 补充1.jpg ├── 补充1.png ├── 补充10.jpg ├── 补充2.jpg ├── 补充2.png ├── 补充3.jpg ├── 补充4.jpg ├── 补充5.jpg ├── 补充6.jpg ├── 补充7.jpg ├── 补充8.jpg ├── 补充9.jpg ├── 超网1.jpg ├── 超网规律1.jpg ├── 跨域1.jpg ├── 跨域2.jpg ├── 跨域3.jpg ├── 跨域4.jpg ├── 跨域5.jpg ├── 跨域6.jpg ├── 路由1.jpg ├── 路由2.jpg ├── 路由3.jpg ├── 路由4.jpg ├── 路由5.jpg ├── 路由表1.jpg ├── 边长子网划分1.jpg ├── 静态路由1.jpg ├── 静态路由2.jpg ├── 静态路由3.jpg ├── 静态路由4.jpg ├── 静态路由5.jpg └── 静态路由6.jpg ├── pkt文件 ├── 1两台电脑直连.pkt ├── 2集线器&网桥.pkt ├── 2集线器.pkt ├── 3交换器.pkt ├── 4交换器&集线器.pkt └── 5路由器.pkt └── 网络设备笔记.txt /1.ip掩码.md: -------------------------------------------------------------------------------- 1 | ### 1.MAC地址 2 | 3 | * 每一个网卡都有一个6字节(48bit)的MAC的值(Media Access Control Address) 4 | 5 | * 全球唯一,(网卡厂商)固化在网卡的存储空间(ROM)中,由IEEE802标准规定 6 | 7 | * 格式: 8 | 9 | * 前3个字节:OUI(Organizationally Unique Identifier),组织唯一标识符。 10 | 11 | 由IEEE的注册管理机构分配给厂商,组织唯一标识符代表网卡厂商。 12 | 13 | * 后3个字节:网络接口标识符 14 | 15 | 由厂商自行分配。 16 | 17 |  18 | 19 | * OUI查询: 20 | 21 | * http://standards-oui.iee.org/oui.txt : 可以查出厂商对应的组织唯一标识符 22 | 23 | * https://mac.51240.com 24 | 25 | * 表示格式: 26 | 27 | * Windows:20-89-84-41-88-09 28 | 29 | * Linux, Android, Mac, IOS:20:89:84:41:88:09 30 | 31 | * Packet Tracer:2089.8441.8809 32 | 33 | * 数据包里面的目标MAC地址是:FFFF.FFFF.FFFF 34 | 35 | * 当我们不知道对方主机的MAC地址时,源计算机会先发送一个ARP广播来获取对方的MAC地址。 36 | 37 | 获取成功后,会缓存IP地址和MAC地址的映射信息,俗称ARP缓存。 38 | 39 | ``` 40 | 说明没有目标MAC地址,也就是希望该区域内的计算机都能收到这个数据包。 41 | 这是一个ARP广播,来查询目的IP的MAC地址的。 42 | ``` 43 | 44 |  45 | 46 | 47 | 48 | * 通过ARP广播获取的MAC地址,属于动态(dynamic)缓存。 49 | 50 | 存储时间比较短(默认是2分钟),过期了就自动删除。 51 | 52 | 53 | ### 2.IP地址 54 | 55 | #### 2.1. 简介 56 | 57 | * IP地址,Internet Protocol Address:互联网上的每一个主机都有一个IP地址。 58 | 59 | * 最初是IPv4版本,32bit(4字节),2019年11月25日,全球的Ip地址已经用完。 60 | 61 | * 后面推出了IPv6版本,128bit(16字节) 62 | 63 | * 后续说到ip地址,默认是ipv4。 64 | 65 |  66 | 67 | #### 2.2. IP地址组成 68 | 69 | * IP地址由2部分组成:网络标识(网络ID),主机标识(主机ID) 70 | 71 | * 同一网段的计算机,网络ID部分相同。 72 | 73 | 74 | #### 2.3. 子网掩码 75 | 76 | * 通过与子网掩码(subnet mask)进行与运算可以计算出网络ID:子网掩码&IP地址 77 | 78 | 11000000 10101000 00000001 00001010 : 192.168.1.10 79 | 80 | 11111111 11111111 11111111 00000000 : 255.255.255.0 81 | 82 | * 两者与&运算结果:网段 83 | 84 | 11000000 10101000 00000001 00000000 :192.168.1.0 85 | 86 | * 子网掩码: 87 | 88 | * 连续的1对应IP地址的那一部分,就是IP地址的网络标识(ID)部分。 89 | * 连续的0对应IP地址的那一部分,就是IP地址的主机ID部分。 90 | 91 | 92 | 93 | * **一个网段所能分配的IP数量**: 94 | 95 | * ip地址的 **主机ID部分 **不能全为0(主机位标识为0时):192.168.1.0 96 | 97 | 所以当结尾是0时,说明这表示网段。 98 | 99 | * ip地址的 **主机ID部分 **不能全是1:192.168.1.255 100 | 101 | 当主机位全是1时,表示这个是一个广播IP地址: 102 | 103 | 可以ping一个网段,来给这个网段内的所有IP发包: 104 | 105 | C: \ >**ping 192.168.1.255** 106 | 107 |  108 | 109 | 如果目标IP地址是192.168.1.255,表示要发给192.168.1.0这个网段内的所有IP地址。 110 | 111 | 112 | 113 | * 所以192.168.1.0网段内的可以分配的ip数量是:192.168.1.1 ~ 192.168.1.254,即256-2。 114 | 115 | 116 | 117 | * 与&运算规律: 118 | 119 | * 与 1 进行与运算,不变 120 | 121 | * 与 0 进行与运算,为0 122 | 123 | * IP地址的两部分 124 | 125 | * 子网掩码:连续的1和连续的0组成 126 | 127 | * 连续的1对应IP地址的那一部分,就是IP地址的网络标识(ID)部分。 128 | 129 | * 连续的0对应IP地址的那一部分,就是IP地址的主机ID部分。 130 | 131 |  132 | 133 | * 计算机和其他计算机进行通信前,会先判断目标主机和自己是否在同一个网段。 134 | 135 | * 同一网段:不需要由路由器进行转发 136 | * 不同网段:需要路由器进行转发 137 | 138 | 139 | 140 | #### 2.4. IP地址的分类 141 | 142 | * A类地址:默认子网掩码是255.0.0.0 143 | 144 | 格式是:0xxxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx 145 | 146 | * B类地址:默认子网掩码255.255.0.0 147 | 148 | 格式是:10xxxxxx.xxxxxxxx.xxxxxxxx.xxxxxxxx 149 | 150 | * C类地址:默认子网掩码255.255.255.0 151 | 152 | 格式是:110xxxxx.xxxxxxxx.xxxxxxx.xxxxxxxx 153 | 154 |  155 | 156 | * D类地址:以1110开头,多播地址。 157 | 158 | * E类地址:以1111开头,保留为今后使用。 159 | 160 | 161 | 162 | * **注意:只有A,B,C类地址才能分配给主机。** 163 | 164 | 165 | 166 | 167 | #### 2.5. A类地址: 168 | 169 | * 判断是不是A类地址 170 | 171 |  172 | 173 | * 网络ID部分 174 | 175 | 0不能用:0.168.100.250,即00000000.00000000.00000000.00000000不能作为一个网段。 176 | 177 | 127作为保留网段,也不能用:其中127.0.0.1是本地环回地址(Loopback),代表本机地址。 178 | 179 | * 可以分配的网段: 180 | 181 | 第一部分取值范围是:1~126 182 | 183 | * 主机ID部分 184 | 185 | * 第2,3,4字节部分的取值范围是 0 ~ 255 186 | * 每个A类网段能容纳的最大主机数是:256 * 256 * 256 - 2 187 | 188 | #### 2.6. B类地址 189 | 190 |  191 | 192 | * 网络ID部分:网段 193 | 194 | 10000000 ~ 10111111 : 128.0 ~ 191.255 195 | 196 | 网段数量:63 * 256 197 | 198 | A类网段中00000000不能作为一个网段,但是10000000可以作为一个网段,因为有一个非0位。 199 | 200 | * 主机ID部分:去掉环回地址和表示网段的地址 201 | 202 | 256 * 256 - 2 203 | 204 | * 所以B类地址一共有:63 * 256 *(256 * 256 - 2)个 205 | 206 | #### 2.7. C类地址 207 | 208 |  209 | 210 | * 网络ID部分: 211 | 212 | 11000000 00000000 00000000 ~ 11011111 11111111 11111111 213 | 214 | 192.0.0 ~ 223.255.255 215 | 216 | 网段数量:31 * 256 * 256 217 | 218 | * 主机ID部分: 219 | 220 | 256 -2 221 | 222 | * 所以C类地址一共有:31 * 256 * 256 * (256 -2) 223 | 224 | #### 2.8. D,E类地址 225 | 226 |  227 | 228 | #### 2.9. 子网掩码的CIDR表示方法 229 | 230 |  231 | 232 | * /24 这部分代表掩码 233 | 234 | ### 3. 子网划分 235 | 236 | #### 3.1. 为什么要进行子网划分 237 | 238 |  239 | 240 | * 为了尽量避免浪费IP地址资源 241 | 242 | 合理地进行子网划分。 243 | 244 | * 子网划分一般有两种: 245 | * 等长子网划分 246 | * 变长子网划分 247 | 248 | #### 3.2. 等长子网划分 249 | 250 |  251 | 252 | * 将主机位取出若干位作为网络位。 253 | 254 | 比如有一个C类网段:192.168.0.0/24。这个网段可用的ip数量:192.168.0.1 ~ 192.168.0.254。 255 | 256 | 但是我只需要100个ip,所以会有154个ip被浪费掉。那么我需要再进行子网划分,且我采用等长子网划分: 257 | 258 | 网段: 11000000 10101000 00000000 00000000 192.168.0.0/24 259 | 260 | 原来子网掩码 11111111 11111111 11111111 00000000 255.255.255.0 261 | 262 | 现在子网掩码 11111111 11111111 11111111 10000000 255.255.255.128 263 | 264 | 此时网络位25位,主机位只有7位,11000000 10101000 00000000 00000000这个网段变成了两个网段: 265 | 266 | 11000000 10101000 00000000 0.0000000 192.168.0.0/25 267 | 268 | 11000000 10101000 00000000 1.0000000 192.168.0.128/25 269 | 270 | 这两个网段分别有128-2 = 126个主机ip。 271 | 272 | * 192.168.0.0/24 273 | 274 | 这个网段的网络位是不变的,因为C类地址默认的网络位是24位。但是如果我们进行子网划分,将从主机位取出若干位作为网络位。 275 | 276 | 一开始只有一个网段,但是后来将这个网段划分,就变成了2个网段了。 277 | 278 |  279 | 280 | #### 3.3. 变长子网划分 281 | 282 | 192.168.0.0/24 等分成: 192.168.0.0/25 和 192.168.0.128/25 283 | 284 | 192.168.0.0 ~ 192.168.0.127 和 192.168.0.128 ~ 192.168.0.255 285 | 286 | 192.168.0.0/25 等分成: 192.168.0.0/26 和 192.168.0.64/26 287 | 288 | 192.168.0.0 ~ 192.168.0.63 和 192.168.0.64 ~ 192.168.0.127 289 | 290 | 192.168.0.0/26 等分成: 192.168.0.0/27 和 192.168.0.32/27 291 | 292 | 192.168.0.0 ~ 192.168.0.31 和 192.168.0.32 ~ 192.168.0.63 293 | 294 | 192.168.0.0/27 等分成: 192.168.0.0/28 和 192.168.0.16/28 295 | 296 | 192.168.0.0 ~ 192.168.0.15 和 192.168.0.16 ~ 192.168.0.31 297 | 298 | 192.168.0.0/28 等分成: 192.168.0.0/29 和 192.168.0.8/29 299 | 300 | 192.168.0.0 ~ 192.168.0.7 和 192.168.0.8 ~ 192.168.0.15 301 | 302 | 192.168.0.0/29 等分成: 192.168.0.0/30 和 192.168.0.4/30 303 | 304 | 192.168.0.0 ~ 192.168.0.3 和 192.168.0.4 ~ 192.168.0.7 305 | 306 |  307 | 308 | 309 | 310 | ### 4. 思考1 311 | 312 | * 这两台设备能通信吗? 313 | 314 |  315 | 316 | 计算机发消息时要先判断目标ip是否和自己在同一网段,比如从左向右发消息,计算机0的掩码是255.255.255.0与目标地址192.168.10.10与运算得到结果是:192.168.10.0。而源ip地址192.168.0.10的网段是192.168.0.0。所以两者显然不在同一个网段。所以从左向右一开始就发布出去。 317 | 318 |  319 | 320 | 321 | 322 | 从右向左:计算机1的网段是192.168.0.0,用自己的(不知道目的计算机的掩码)掩码判断目标地址192.168.0.10的网段是192.168.0.0。发现网段是一样的,那么从右向左能发出去。然是发出去后,还要能接收,经历一次从左向右发送消息。计算机0再判断是否同一个网段时,就会发现不在同一个网段。从左向右发布出去。 323 | 324 |  325 | 326 | * 一种特殊情况: 327 | 328 |  329 | 330 | 从左向右:判断目的ip192.168.0.11的网段是192.168.0.0 331 | 332 | 从右向左:判断目的ip192.168.0.10的网段是192.168.0.0 333 | 334 | 所以这两个ip能通信:192.168.0.10/24 和 192.168.0.11/16。 335 | 336 | 主要看计算机发信息时判断源ip和目的ip是否在同一个网段的结果。 337 | 338 | ### 5. 超网 339 | 340 |  341 | 342 | * 注意必须是连续的网段才能合并。 343 | 344 | ### 6. 思考2 345 | 346 | * 192.168.0.255/21这个ip地址,可以分配给计算机使用吗? 347 | 348 | 分析:如果主机位全是0或全是1,那就不能分配给计算机。 349 | 350 | 192.168.0.255与掩码与运算: 351 | 352 | 11000000 10101000 00000000 11111111 353 | 354 | 11111111 11111111 11111000 00000000 355 | 356 | 11000000 10101000 00000000 00000000:192.168.0.0 357 | 358 |  359 | 360 | 发现主机位不全是1,也不全是0,所以可以分配给计算机。 361 | 362 | * 这个网段192.168.0.255/21的广播地址是: 363 | 364 | 11000000 10101000 00000111 11111111 365 | 366 | 192.168.7.255 367 | 368 | ### 7. 网段合并规律 369 | 370 |  371 | 372 |  373 | 374 | ### 8. 判断一个网段是子网还是超网 375 | 376 | 1. 首先判断该网段的类型:A, B, C 377 | 378 | 2. 在判断和默认的子网掩码相比,当前的掩码是向左移还是向右移。 379 | 380 | 3. 左移:超网;右移:子网。 381 | 382 | 4. 比如: 383 | 384 | 25.100.0.0/16是一个A类子网 385 | 386 | 00011001 01100100 00000000 00000000 387 | 388 | 11111111 11111111 00000000 00000000 得到网段 00011001 01100100 .0.0 -- 25.100 389 | 390 | 而A类地址原本的子网掩码是:255.0.0.0,网段是25;现在掩码255.255.0.0,网段25.100 391 | 392 | 所以网段变小了,是一个A类子网。 393 | 394 | 395 | 396 | 200.100.0.0/16是一个C类超网 397 | 398 | 11011100 01100100 00000000 00000000 399 | 400 | 11111111 11111111 00000000 00000000 401 | 402 | C类地址:主机位8位;改地址:主机位16位,所以是一个C类超网 403 | 404 | -------------------------------------------------------------------------------- /10.网络安全.md: -------------------------------------------------------------------------------- 1 | #### 10.网络安全 2 | 3 | 网络通信中面临的4种安全威胁 4 | 5 | 1.截取:窃听通信内容 6 | 7 | 2.中断:中断网络通信 8 | 9 | 3.篡改:篡改通信内容 10 | 11 | 4.伪造:伪造通信内容。 12 | 13 | ##### 1.HTTP协议的安全问题 14 | 15 | ###### 1.概述 16 | 17 | HTTP协议默认是采取明文传输的(没有加密,数据包被拦截到就能直接看到),因此有很大的安全隐患。 18 | 19 | 常见的加密方式有: 20 | 21 | 1.不可逆 22 | 23 | 单向散列函数:MD5,SHA等 24 | 25 | 2.可逆 26 | 27 | 对称加密:DES,3DES,AES等 28 | 29 | 非对称机密:RSA等 30 | 31 | 3.其他 32 | 33 | 混合密码系统,数字签名,证书。 34 | 35 | ###### 2.常见英文 36 | 37 | encrypt:加密 38 | 39 | decrypt:解密 40 | 41 | plaintext:明文 42 | 43 | ciphertext:密文 44 | 45 | ###### 3.背景假设 46 | 47 | 1.为了便于学习,设计4个虚拟人物 48 | 49 | Alice,Bob:互相通信 50 | 51 | Eve:窃听者 52 | 53 | Mallory:主动攻击者。 54 | 55 | 2.通过加密防止被窃听: 56 | 57 | ##### 2.单向散列函数 58 | 59 | ###### 1.概述 60 | 61 | 单向散列函数:One-way hash function 62 | 63 | 1.单向散列函数,可以根据消息内容计算出散列值 64 | 65 | 2.散列值的长度和消息的长度无关,无论消息是1bit,10M,100G,单向散列函数都会计算出固定长度的`散列值`。 66 | 67 | 3.单向散列函数的特点 68 | 69 | 1.根据任意长度的消息,计算出固定长度的散列值。 70 | 71 | 2.计算速度快,能快速计算出散列值 72 | 73 | 3.消息不同,散列值也不同 74 | 75 | 4.具备单向性:设计初的目的就是,无法根据散列值得到原数据。(现在可能被破解了) 76 | 77 | 5.哪怕原数据只有1bit的区别,也会产生完全不同的散列值。 78 | 79 | 4.单向散列函数的其他称呼 80 | 81 | 1.单向散列函数也被称为 82 | 83 | 消息摘要函数(Message digest function) 84 | 85 | 哈希函数(hash function) 86 | 87 | 2.输出的散列值,也被称为 88 | 89 | 消息摘要(message digest) 90 | 91 | 指纹(fingerprint) 92 | 93 | 5.常见的单向散列函数 94 | 95 | MD4,MD5: 96 | 97 | 产生128bit的散列值,MD就是Message Digest的缩写,目前已经不安全。 98 | 99 | SHA-1 100 | 101 | 产生160bit的散列值,目前已经不安全 102 | 103 | SHA-2 104 | 105 | SHA-256,SHA-384,SHA-512,散列值长度分别是256bit,384bit,512bit 106 | 107 | SHA-3 108 | 109 | 全新标准 110 | 111 | ###### 2.单向散列函数的应用 112 | 113 | 1.防止数据被篡改 114 | 115 | 为将要检测的数据计算出一个散列值,通过检测这个数据的散列值是否发生了改变,来判断数据是否改变。 116 | 117 |  118 | 119 | 2.密码加密 120 | 121 |  122 | 123 | ##### 3.对称加密和非对称加密:是可逆的加密 124 | 125 | ###### 1.对称加密Symmetric Cryptography: 126 | 127 | 对称加密中,加密用的密码和解密用的密钥是相同的。 128 | 129 | 主要两个组成部分:加密算法和密钥 130 | 131 | 常见的对称加密算法: 132 | 133 | 1.1DES(Data Encryption Standard) 134 | 135 | 只能一次性将64bit明文加密成64bit密文的对称加密算法,密钥程度是56bit; 136 | 137 | 规格上来说,密钥长度是64bit,但是每隔7bit会设置一个用于错误检查的bit,因此密钥长度实际上是56bit。 138 | 139 | 由于DES每次只能加密64bit的数据,遇到比较大的数据,需要对DES加密进行迭代(反复)。 140 | 141 | 目前已经可以在短时间内被破解,所以不建议使用。 142 | 143 | 1.23DES(Triple Data Encryption Standard) 144 | 145 | 将DES重复3次所得到的一种加密算法,也叫做3重DES 146 | 147 | 三重DES并不是进行三次DES加密(加密->加密->加密),而是(加密->解密->加密)的过程,这个过程中加密解密的密钥不同。 148 | 149 | 目前还被一些银行机构使用,但是处理速度不高,安全性逐渐暴露出问题。 150 | 151 | 1.3AES(Advanced Encryption Standard) 152 | 153 | 取代DES称为新标准的一种对称加密算法,又称Rijndae加密法 154 | 155 | AES的密钥长度有128,192,256bit三种 156 | 157 | 目前AES,已经逐步取代DES,3DES,成为首选的对称加密算法。 158 | 159 | 一般来说,我们也不应该去使用任何自制的密码算法,而是应该使用AES 160 | 161 | 它经过了全世界密码学家所进行的高品质的验证工作。 162 | 163 | 2.非对称加密(公钥密码): 164 | 165 | 加密用的密钥和解密用的密钥是不同的。 166 | 167 | ###### 2.密钥配送问题 168 | 169 | 1.在使用对称加密时,一定会遇到密钥配送问题。 170 | 171 | 如果Alice将使用对称加密过的消息发送给Bod,那么两者必须协商好加密算法,并且Alice要将密钥发送给Bod。只有这样Bod才能完成解密。 172 | 173 | 但是在发送密钥过程中,可能会遇到问题: 174 | 175 | 可能会被Eve窃取到密钥。 176 | 177 | 最后Eve也能完成解密。 178 | 179 | 2.如何解决密钥配送问题 180 | 181 | 有以下几种解决密钥配送的方法 182 | 183 | 实现共享密钥(比如私下共享) 184 | 185 | 密钥分配中心 186 | 187 | Diffie-Hellman密钥交换 188 | 189 | `非对称加密` 190 | 191 | 3.非对称加密解决密钥配送问题: 192 | 193 | 194 | 195 | ###### 3.非对称加密Asymmetric Cryptography 196 | 197 | 1.在非对称加密中,密钥分为加密密钥,解密密钥2中,它们并不是同一个密钥。 198 | 199 | 2.加密密钥:一般是公开,因此该密钥称为公钥(public key) 200 | 201 | 3.私密密钥:由消息接收者自己保管的,不能公开,因此也称为私钥(private key) 202 | 203 | 4.公钥和私钥是一一对应的,不能单独生成。一对公私钥是`针对一个接收端的`。 204 | 205 | 5.由公钥加密的密文,必须使用与该公钥对应的私钥才能解密。 206 | 207 | 6.由私钥加密的密文,必须使用与该私钥对应的公钥才能解密。 208 | 209 | 因为公钥是公开的,那用私钥加密的东西,都会被其他端用公钥解密。 210 | 211 | 有其特定用途:数字签名 212 | 213 | 7.目前使用最广泛的非对称加密算法是RSA,是三位开发者名字的首字母组成。 214 | 215 | 8.非对称加密的加密解密速度比对称加密要慢,但是比要安全的多。 216 | 217 | 怎么解决加密解密速度慢这个问题呢? 218 | 219 | ###### 4.混合密码系统(Hybrid Cryptosystem) 220 | 221 | 1.对称加密的缺点 222 | 223 | 不能很好地解决密钥配送问题(密钥会被窃听)。 224 | 225 | 2.非对称加密的缺点 226 | 227 | 加密解密速度比较慢 228 | 229 | 3.混合密码系统:是将对称加密和非对称加密的优势相结合的方法。 230 | 231 | 解决了非对称加密速度慢的问题 232 | 233 | 并通过非对称加密解决了对称加密的密钥配送问题。 234 | 235 | 4.网络上的密码通信所用的SSL/TLS都运用了混合密码系统。 236 | 237 | 5.原理 238 | 239 | 我们一般通信时,两端传输的数据都不会太小,那么如果都用非对称加密对这些数据加密的话,会是个非常低效的过程,那么就又混合密码系统来解决这个问题: 240 | 241 | 思路:既然非对称加密加密解密数据很慢,那么就用对称加密加密解密数据;同时对对称加密的密钥进行非对称加密后再传给接收端(这个密钥的数据量很小:所以用非对称加密来安全加密)。 242 | 243 | `即用对称加密来加密解密数据,非对称加密来加密解密对称加密的密钥。` 244 | 245 | 所以最终发送给接收端的是两部分:用公钥密码加密的会话密钥(对称加密的密钥)和用对称密钥加密的数据部分。 246 | 247 | 会话密钥(session key):为本次通信随机生成的临时密钥,作为对称加密的密钥,用于加密消息,提高速度。 248 | 249 |  250 | 251 | 6.加密步骤 252 | 253 | 1.首先,消息发送者要拥有消息接收者的公钥 254 | 255 | 2.生成会话密钥,作为对称加密的密钥,加密消息 256 | 257 | 3.用消息接收者的公钥,加密会话密钥。 258 | 259 | 4.将2,3两步生成的加密结果,一并发送给消息接收者。 260 | 261 | 7.发送出去的内容包括: 262 | 263 | 1.用会话密钥加密的消息(加密方法:对称加密) 264 | 265 | 2.用公钥加密的会话密钥(加密方法:非对称加密) 266 | 267 | ##### 4.数字签名:确定消息是发送者发的 268 | 269 | ###### 1.概述 270 | 271 | 1.想象以下场景: 272 | 273 | Alice发的内容有可能是被篡改过的,或者有人伪装成Alice发消息,或者就是Alice发的,但她可能会否认。 274 | 275 | 问题来了:Bob如何确定这段消息的真实性呢?如何识别篡改,伪装,否认呢? 276 | 277 | 2.解决方案:数字签名。 278 | 279 | 在数字签名技术中,有以下2种行为 280 | 281 | 生成签名:由消息的发送者完成,通过“签名密钥”生成。 282 | 283 | 验证签名:由消息的接收者完成,通过“验证密钥”验证。 284 | 285 | 3.但是签名也可能被篡改伪造。 286 | 287 | 如何能保证这个签名是消息发送者自己签的呢? 288 | 289 | 用消息发送者的私钥进行签名:因为私钥只有消息发送者才有,那么能被发送者公钥解密的签名,一定是发送者生成的签名。 290 | 291 | ###### 2.数字签名:过程 292 | 293 |  294 | 295 | 注意: 296 | 297 | 假设发送的消息部分是明文:这个消息我不在乎其他人能不能看到,我只想证明这个消息是我发的,没有被其他人篡改。 298 | 299 | Alice消息发送者生成密钥对:用来做签名 300 | 301 | Alice发送给Bob的数据包括两部分:签名和消息 302 | 303 | Alice用自己的私钥对消息进行加密后得到的密文,称为签名。 304 | 305 | 接收者Bob会用Alice的公钥对签名进行解密得到消息,再和直接接收到的消息进行对比,如果两者一致,则签名验证成功:说明消息是Alice发送的且没有被篡改。 306 | 307 | 也可以结合非对称加密,对消息加密。(此时还需要接收者生成密钥对) 308 | 309 | 缺点: 310 | 311 | 发送者对消息进行私钥加密,公钥解密,这是非对称加密,而整个消息部分一般数据量较大,所以效率低下。 312 | 313 | ###### 3.数字签名:改进 314 | 315 | 缺点回顾: 316 | 317 | 发送者对消息进行私钥加密,公钥解密,这是非对称加密,而整个消息部分一般数据量较大,所以效率低下。 318 | 319 | 思路: 320 | 321 | 结合单向散列函数,无论数据有多大,运用散列函数都可以生成固定长度的散列值。这个散列值就代表着消息数据(可以理解为数据的id),可以对散列值进行私钥加密,得到签名。 322 | 323 | 那么接收者收到数据后,用公钥解密签名得到的散列值和直接接收的消息的散列值进行比较,判断是两者否一致。来确定消息是否是发者发送的。 324 | 325 |  326 | 327 | ###### 4.数字签名 - 疑惑 328 | 329 | 1.如果有人篡改了消息内容或签名内容,会是什么结果? 330 | 331 | 签名验证失败,证明内容被篡改了。 332 | 333 | 2.数字签名不能保证机密性? 334 | 335 | 数字签名的作用不是为了保证机密性,仅仅是为了能够识别内容有没有被篡改。 336 | 337 | 3.数字签名的作用 338 | 339 | 确认消息的完整性 340 | 341 | 识别消息是否被篡改 342 | 343 | 防止消息发送人否认。 344 | 345 | ##### 5.非对称加密 - 公钥私钥总结 346 | 347 | 1. 签名可以理解成一种公开的加密:只是为了告诉接收者消息是我发送的。 348 | 2. 数字签名:其实就是将非对称加密反过来使用: 349 | 3. 非对称加密:`接收者只希望只有自己才能对消息进行解密`,因为私钥是不公开的,那么肯定是私钥解密,希望发送者拿着接收者的公钥对消息进行加密。 350 | 4. 数字签名:`消息发送者不希望别人冒充我发消息`,只有我能签名,所以用消息发送者的私钥进行加密,消息接收者用发送者的公钥进行解密。 351 | 352 | ##### 6.证书 353 | 354 | ###### 1.公钥的合法性问题; 355 | 356 |  357 | 358 | 1.消息接收者,在发送公钥给消息发送者时,公钥可能会被攻击者拦截到。那么拦截者可能会把拦截者的公钥发给发送者,发送者用拦截者的公钥加密的消息发送时,这个消息被拦截者拦到后,就可以被拦截者自身的私钥解密。而且拦截者还可以在改造一下消息,再用接收者的公钥加密后发送给接收者,接收者就会受到一个被篡改的消息(没有用数字签名:所以篡改不会被发现)。 359 | 360 | 2.所以在互联网上,非对称加密消息时,会将公钥发送给消息发送者,那么就可能会遇到中间者攻击拦截公钥。再发送自己的公钥给消息发送者,所以怎么确保公钥的合法性呢?怎么防止别人伪造我得公钥呢? 361 | 362 | 3.公钥在互联网上传输导致的问题:那么怎么保证这个公钥是消息接收者的呢? 363 | 364 | 其实还是签名机制来保证,用接收者的私钥要对公钥加密得到一个公钥签名,将公钥签名和公钥一起发送给消息发送者,消息发送者用接收者的公钥解密公钥签名得到公钥,再和公钥对比是否被篡改吗? 365 | 366 | 4.但这样其实没有解决问题: 367 | 368 | 拦截者只要保证发送者解密后得到的公钥和接收的公钥一致即可。所以可以用拦截者的私钥对拦截者公钥加密的都公钥签名,再和拦截者公钥一起发过去,还是可以欺骗消息接收者。 369 | 370 | 因为要把公钥和公钥签名都发给消息发送者,那么如果中间又被拦截到后。拦截者再多做一步操作呗,将拦截者的公钥用拦截者私钥加密后,再和拦截者的公钥一起发送给接收者。那么消息发送者用的是拦截者的公钥对公钥签名解密,最后还是会认为公钥没有问题。 371 | 372 | ###### 2.证书:Certificate 373 | 374 | 所以靠个人签名不能保证公钥不被拦截,所以我们需要依赖一个权威的中间机构,来为公钥做担保。 375 | 376 | 1.密码学中的证书,全称叫做公钥证书(public-key certificate, PKC),里面主要包括三部分 377 | 378 | 姓名,邮箱等个人信息。 379 | 380 | 此人的公钥 381 | 382 | 由认证机构(Certificate Authority, CA)施加数字签名:机构用其私钥加密注册者的公钥。 383 | 384 | 2.CA就是能够认定“公钥确实属于此人并能够生成数字签名的个人或者组织。 385 | 386 | ###### 3.证书使用 387 | 388 |  389 | 390 | 考虑一个问题:如果注册的证书和认证机构的签名在给Alice的过程中,被拦截到了。拦截者此时自己作为一个“认证机构”自己做了一个证书,再将证书和自己的公钥传给Alice,不是也能欺骗Alice吗? 391 | 392 | 这个概率非常小,毕竟是认证机构。那么肯定是被广范围认可的,接收者只认可这个认证机构的证书,别人想模仿难度很大。当然无法保证绝对的安全,但是尽量缩小不安全的概率。 393 | 394 | 事实上,各大CA的公钥,默认已经内置在浏览器和操作系统中了。所以不需要再去其他地方下载公钥了,浏览器中的公钥就是合法的公钥。 395 | 396 | 安全都是相对的,只能尽量提高安全性。 397 | 398 | ###### 4.证书的注册和下载 399 | 400 |  401 | 402 | ###### 5.查看Windows已经信任的证书 403 | 404 |  -------------------------------------------------------------------------------- /11.HTTPS.md: -------------------------------------------------------------------------------- 1 | #### 11.HTTPS 2 | 3 | ##### 1.概述 4 | 5 | 1.HTTPS(HyperText Transfer Protocol Secure),译为超文本传输安全协议。 6 | 7 | 常称为HTTP over TLS,HTTP over SSL,HTTP Secure。由网景公司于1994年首次提出,HTTPS是在HTTP的基础上使用SSL/TLS来加密报文,对窃听和中间人攻击提供合理的防护。 8 | 9 | HTTPS就是身披SSL/TLS外壳的HTTP。HTTPS是一种通过计算机网络进行安全通信的传输协议,经由HTTP进行通信,利用SSL/TLS建立安全信道,加密数据包。HTTPS使用的主要目的是提供对网站服务器的身份认证,同时保护交换数据的隐私与完整性。 10 | 11 | 2.HTTPS的默认端口号是443(HTTP是80) 12 | 13 | 3.在浏览器上输入http://www.baidu.com会自动重定向到https://www.baidu.com 14 | 15 |  16 | 17 | 4.HTTPS的成本 18 | 19 | 证书的费用 20 | 21 | 加解密计算 22 | 23 | 降低了访问速度 24 | 25 | 有些企业的做法是:包含敏感数据的请求才使用HTTPS,其他保持使用HTTP 26 | 27 | ##### 2.SSL/TLS 28 | 29 | TLS(Transport Layer Security),译为:传输层安全性协议,前身是SSL(Secure Sockets Layer),译为:安全套接层。 30 | 31 | SSL/TLS工作在哪一层:应用层和传输层之间。要将HTTP报文加密后,在发给传输层。其中SSL/TLS这一层又分为握手层和记录层。 32 | 33 |  34 | 35 | ##### 3.OpenSSL 36 | 37 | OpenSSL是SSL/TLS协议的开源实现,始于1998年,支持Windows,Mac,Linux等平台。利用OpenSSL可以使用SSL/TLS的一些功能,比如加密,生成密钥对,生成签名证书。 38 | 39 | Linux,Mac一般自带OpenSSL 40 | 41 | Windows下载安装OpenSSL:https://slproweb.com/products/Win32OpenSSL.html 42 | 43 | 常用命令: 44 | 45 | 生成私钥:openss genrsa -out mj.key 46 | 47 | 生成公钥:open rsa -in mj.key -pubout -out mj.pem 48 | 49 | 可以使用OpenSSL构建一套属于自己的CA,自己给自己颁发证书,称为“自签名证书”。 50 | 51 | ##### 4.HTTPS的通信过程 52 | 53 | 1.总的可以分为3大阶段: 54 | 55 | 1.TCP的3次握手 56 | 57 | 2.TLS的连接: 58 | 59 | 主要就是协商各种信息,利用密钥交换算法来生成一个会话密钥,之后就可以进行HTTP通信。 60 | 61 | 主要协商内容:协定加密组件,TLS版本,计算出会话密钥,将公钥证书(包含公钥)给客户端 62 | 63 | 3.HTTP请求和响应: 64 | 65 | `之后HTTP的请求响应过程:就是用TLS连接得到的会话密钥来对数据进行对称加密;服务器的公钥对会话密钥进行加密(非对称加密)。`再加上签名等机制。 66 | 67 | 所以非对称加密,对称加密, 68 | 69 |  70 | 71 | 72 | 73 | 2.TLS 1.2的连接 74 | 75 | 大概有10大步骤,图片中省略了中间产生的一些ACK确认。 76 | 77 | 抓包可以看到这些ACK过程。 78 | 79 |  80 | 81 |  82 | 83 | ##### 5.TLS 1.2的连接 84 | 85 | #####  86 | 87 | 步骤1:Client Hello 88 | 89 | 客户端向服务器发送一个数据包,主要协定这些内容 90 | 91 | TLS的版本号; 92 | 93 | 支持的加密组件(Cipher Suiter)列表,加密组件是指所使用的的加密算法以及密钥长度。 94 | 95 | 一个客户端随机数(Client Random) 96 | 97 |  98 | 99 | 步骤2:Server Hello 100 | 101 | 服务器向客户端发送一个数据包,主要包括下面内容 102 | 103 | TLS的版本号 104 | 105 | 选择的加密组件:是从接收到的客户端机密组件列表中挑选出来的。 106 | 107 | 一个随机数。 108 | 109 |  110 | 111 | 步骤3:Cetificate 112 | 113 | 服务器将公钥证书(被CA签名过的),发给客户端。 114 | 115 | 证书里面包含着公钥,第三方认证机构的签名信息,服务端域名信息等 116 | 117 |  118 | 119 | 步骤4:Server Key Exchange 120 | 121 | 传给客户端一个用以实现ECDHE算法的其中一个参数(Server Params) 122 | 123 | `ECDHE是一种密钥交换算法:客户端和服务端都要拥有密钥,就是根据TLS的前几部,协定一些参数,然后两端根据参数都能计算出一个相同的密钥。` 124 | 125 | 为了防止伪造,Server Params经过了服务器私钥签名。 126 | 127 |  128 | 129 | 步骤5:Server Hello Done 130 | 131 | 告知客户端,协商部分结束。 132 | 133 | 目前为止,客户端和服务器端之间通过明文(前5不都是明文)共享了: 134 | 135 | Client Random, Server Random, Server Params 136 | 137 | 而且,客户端也已经拿到了服务器的公钥证书,接下来,客户端会验证证书的真实有效性。 138 | 139 | 步骤6:Client Key Exchange 140 | 141 | 客户端解析证书,这部分工作由客户端来完成。首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在的问题。如果证书没有问题,那么就开始生成主密钥的步骤。 142 | 143 | 客户端发给服务器:用以实现ECDHE算法的另一个参数(Client Params) 144 | 145 | 目前为止,客户端和服务器端都拥有的ECDHE算法需要的2个参数:Server Params, Client Params 146 | 147 | 此时客户端,服务器都可以使用ECDHE算法: 148 | 149 | 根据Server Params, Client Params计算出一个新的随机密钥串:Pre-master secret 150 | 151 | 然后结合Server Params, Client Params,Pre-master secret生成一个主密钥,最后再利用主密钥衍生出其他密钥而且双方都有这些密钥:客户端发送用的会话密钥,服务器端发送用的会话密钥。 152 | 153 | 会话密钥就是对HTTP请求发送的内容进行对称加密,如果用的是别的密钥交换算法算法的话(此处的密钥交换算法ECDHE是两边都算出主密钥,会话密钥),这个会话密钥本身又会被非对称加密后传输给接收端(用接收的证书的公钥加密会话密钥)。 154 | 155 | 步骤7:Change Cipher Spec 156 | 157 | 告知服务器:之后的通信会采用计算出来的会话密钥(对称加密的密钥)进行加密。 158 | 159 | 步骤8:Finished 160 | 161 | 看一些你的密钥有没有问题:客户端发给服务器,看看服务器能不能解密。 162 | 163 | 发送一个包含连接至今全部报文的整体校验值(摘要,哈希值),并且用上面得到的会话密钥加密这个密钥之后发送给服务器。 164 | 165 | 这次握手协商能否成功:要以服务器是否能够正确解密该报文作为判定标准。 166 | 167 | 步骤9,10 168 | 169 | Change Cipher Spec和Finished 170 | 171 | 客户端正确解密后,会连续发送两次报文给客户端。 172 | 173 | 到此为止,客户端服务器都验证加密解密没问题,握手正式结束,表明TSL层连接建立成功。 174 | 175 | 后面开始传输加密的HTTP请求和响应。 176 | 177 | 之后HTTP的请求响应过程:就是用TLS连接得到的会话密钥来对数据进行加密解密。 178 | 179 | ###### 5.1注意: 180 | 181 | 这是以ECDHE是一种密钥交换算法为例进行讲解的TLS连接,所以看到的其他的TLS连接可能和上面有细节差别。取决于用的是什么密钥交换算法,怎么搞定两边都有主密钥的。是左右两个各自计算,还是左边计算好传过去呢? 182 | 183 | 如果用的是别的密钥交换算法算法的话(此处的密钥交换算法ECDHE是两边都算出主密钥,会话密钥),这个会话密钥本身又会被非对称加密后传输给接收端(用接收的证书的公钥加密会话密钥)。 184 | 185 | TLS主要就是能两边建立一个安全的信道,安全的传输信息,怎么让两边安全的都有这个会话密钥 186 | 187 | ##### 6.Wireshark解密HTTPS 188 | 189 | 1.设置环境变量SSLKEYLOGFILE(浏览器会将key信息导出到这个文件) 190 | 191 |  192 | 193 | 设置完成后,最好重启一下操作系统 194 | 195 | 2.在Wireshark中选择这个文件 196 | 197 | 编辑 → 首选项 → Protocols → TLS 198 | 199 | 3.如果环境变量不管用,可以直接设置浏览器的启动参数 200 | 201 |  202 | 203 | ##### 7.服务器配置HTTPS - 生成证书 204 | 205 | 1.主要就是让浏览器从后端能下载一个证书,前端不用什么工作,因为浏览器可以自己解析证书。 206 | 207 | 环境:Tomcat 8, JDK1.8 208 | 209 | 2.首先,使用JDK自带的keytool生成证书。 210 | 211 |  212 | 213 | 一个生成免费证书的网站: https://freessl.org/ 214 | 215 | 证书:里面会放一个我的公钥,我的私钥自己保管,不对外开放。所以选择这个命令 216 | 217 |  218 | 219 | 220 | 221 | ```markdown 222 | keytool -genkeypair -alias mj -keyalg RSA -keystore F:/mj.jks 223 | ``` 224 | 225 |  226 | 227 | 3.配置服务器: 228 | 229 | 把生成的mj.jks放到tomcat目录下的conf文件夹中 230 | 231 | 4.修改 TOMCAT_HOME/conf/server.xml 中的 Connector,之后重启一下tomcat 232 | 233 |  234 | 235 | 5.当然浏览器会提示不安全,因为这个证书不是第三方签发的,是我们自己生成的,浏览器不信任。 -------------------------------------------------------------------------------- /12.HTTP协议的升级改进.md: -------------------------------------------------------------------------------- 1 | #### 12.HTTP协议的升级改进 2 | 3 | HTTP:HTTP和HTTPS都可以理解为HTTP。 4 | 5 | ##### 1.HTTP协议的不足(HTTP/1.1) 6 | 7 | 1.同一时间,一个连接只能对应一个请求: 8 | 9 | HTTP1.0:发送一个请求,要建立一个连接,通信完毕后,连接就会断开。如果还有下一次请求,那么还得建立一个新的连接,通信完毕后,连接再断开。 10 | 11 | HTTP1.1:建立一个长连接后,在这次连接中可以发多个请求,请求都发完后,连接才会断开。但是在这个通信过程中,这些多个请求是排队发送的,所以同一时间还是只能发送一个请求。HTTP1.1建立的一个连接可以复用,但是同一时间只能发送一个请求,所以说同一时间,一个连接只能对应一个请求。 12 | 13 | 那么以前浏览器为了并发的话,就会创建多个连接对象,建立多个HTTP连接。 14 | 15 | 针对同一域名,一个浏览器最多允许同时最多6个并发连接。 16 | 17 | 2.只允许客户端主动发起请求:服务器无法主动响应; 18 | 19 | 是一种请求应答模式。 20 | 21 | 一个请求只能对应一个响应。 22 | 23 | HTTP1.1通信过程中,我们想要加载一个网站,例如JD。客户端发送一个请求:jd.com后,服务器做不到一起返回多个文资源给我,比如很多图片啊,CSS,JS啊,服务器无法主动做到这一点。 24 | 25 |  26 | 27 | 例如请求jd.com后,页面中的css,图片等资源,服务器无法一次全部返回给浏览器。需要再次分次请求这些资源,服务器再单个应答。 28 | 29 | HTTP1.1中,服务器只能是请求应答的模式。浏览器请求服务器一次,服务器返回一次资源,而且请求只能由客户端发起。服务器做不到,一下子把所有的资源都发给浏览器。 30 | 31 | 3.同一个会话的多次请求中,头信息会被重复传输。 32 | 33 | 比如在Session会话技术中,登陆成功后,服务器返回一个Set-Cookie响应头,告诉浏览器存储下来。之后,浏览器为了证明自己的身份,每次请求都会带着Cookie请求头信息,去请求服务器。 34 | 35 | 通常会给每个传输增加500~800字节的开销。 36 | 37 | 如果使用Cookie,增加的开销有时会达到上千字节。即每次请求都会重复传输这上千字节的数据。 38 | 39 | ##### 2.SPDY 40 | 41 | 1.SPDY(speedy的缩写),是基于TCP的应用层协议,它强制要求使用SSL/TLS。2009年11月,Google宣布将SPDY作为提高网络素的内部项目。 42 | 43 | 2.SPDY与HTTP的关系: 44 | 45 | SPDY并不用于取代HTTP,它只是修改了HTTP请求与相应的传输方式。 46 | 47 |  48 | 49 | HTTP升级到SPDY:只需要在HTTP下面增加一个SPDY层,现有的所有服务端应用均不用做任何修改。 50 | 51 | 3.SPDY是HTTP/2的前身 52 | 53 | 2015年9月,Google宣布移除对SPDY的支持,拥抱HTTP/2。 54 | 55 | ##### 3.HTTP2 56 | 57 | ###### 1.概述 58 | 59 | 1.HTTP/2,于2015年5月以RFC 7540正式发表。 60 | 61 | 根据W3Techs的数据,截至2019年6月,全球有36.5%的网站支持了HTTP/2 62 | 63 | 2.HTTP/1.1和HTTP/2的速度对比 64 | 65 |  66 | 67 |  68 | 69 | 3.HTTp/2在底层传输做了很多的改进和优化,但在语意上完全与HTTP/1.1兼容。 70 | 71 | 比如请求方法(如GET,POST),Status Code,各种Headers等都没有改变, 72 | 73 | 因此,想要升级到HTTP/2:开发者不需要修改任何代码,只需要升级服务器配置,升级浏览器。 74 | 75 | 所以HTTP/1.1迁移到HTTP/2非常容易。 76 | 77 | 4.注意 78 | 79 | TCP和IP这两层是操作系统内核在处理,所以要想用到TCP的一些新特性,就要升级修改操作系统的内核非常麻烦,所以很多TCP的新特性根本就没用到。 80 | 81 | HTTP/2标准没有强制要求使用SSL/TSL,但是目前绝大多数的HTTP/2连接都使用了SSL/TSL。 82 | 83 | ###### 2.HTTP2的特性 - 二进制格式 84 | 85 | 1.HTTP/1.1采用的是文本格式传输数据,本质上就是字符串。而HTTP/2采用二进制格式传输数据。 86 | 87 | 以前的请求头信息变成了Headers Frame二进制头帧,请求体部分变成了Data Frame二进制数据帧。 88 | 89 |  90 | 91 | 二进制格式在协议的解析和优化扩展上带来更多的优势和可能。 92 | 93 | 2.HTTP/2的特性:多路复用(Multiplexing) 94 | 95 | 客户端和服务器可以将HTTP消息分解为互补依赖的帧,然后交错发送,最后再在另一端把他们重新组装起来。 96 | 97 | 并行交错的发送多个请求,请求之间互不影响;并行交错的发送多个响应,响应之间互不干扰。 98 | 99 | 使用一个连接并行发送多个请求和响应。 100 | 101 |  102 | 103 | 不必再为绕过HTTP/1.1的限制而做很多工作: 104 | 105 | 限制: 106 | 107 | 同一时间,一个连接只能对应一个请求。 108 | 109 | 只允许客户端主动发起请求。 110 | 111 | 同一个会话的多次请求中,头信息会被重复传输。 112 | 113 | 做的工作: 114 | 115 | 比如image sprites、合并CSS,JS、内嵌CSS,JS,Base64图片、域名分片等。 116 | 117 | HTTP/1.1和HTTP/2请求三个文件的对比: 118 | 119 |  120 | 121 | 3.HTTP/2标准允许每个数据流都有一个关联的权重和依赖关系 122 | 123 | 可以向每个数据流分配一个介于1至256之间的整数:优先级 124 | 125 | 每个数据流与其他数据流之间可以存在显示依赖关系。 126 | 127 | 客户端通过构建和传递:“优先级树”,表明它倾向于如何接受响应;服务器可以根据此信息,通过控制CPU,内存和其他资源的分配设定数据流处理的优先级。 128 | 129 | 在资源数据可用之后,确保将高优先级响应以最快方式传输至客户端。 130 | 131 | 优先级确定过程: 132 | 133 |  134 | 135 | 4.头部压缩 136 | 137 | 会追踪以前请求发送的请求头信息,已经发过的请求头,就不会再发送了。 138 | 139 |  140 | 141 | HTTP/2使用HPACK压缩请求头和响应头,可以极大减少头部开销,进而提高性能。 142 | 143 | 早起版本的HTTP/2和SPDY使用zlib压缩:可以将所传输头数据的大小减小85%~88%,但在2012年夏天,被攻击导致会话劫持,后被更安全的HPACK取代。 144 | 145 | 5.服务器推送 146 | 147 | 要注意:只要是HTTP请求,服务器端就不能在没有请求的情况下,主动发数据给浏览器。 148 | 149 | HTTP/2也一样,只是服务器可以对一个请求,返回多个响应。除了对开始的请求的响应外,服务器还而已向客户端推送额外资源,而无需客户端额外明确地请求。 150 | 151 | 请求一个HTML页面,服务器发现HTML还有CSS,图片等资源。那么就响应多次资源,将CSS,图片一并响应过去。 152 | 153 |  154 | 155 | ###### 3.HTTP/2的一些基本概念 156 | 157 | 1.数据流:已建立的连接内的`双向`字节流,可以承载一条或多条消息。 158 | 159 | 每个`双向`字节流可以理解成一个请求。 160 | 161 | 数据流是一个逻辑上的概念,每个数据流的存在性是依靠每个帧头的数据流标识符而存在。 162 | 163 | 所有通信都在一个TCP连接上完成,同一时间,此连接可以承载任意数量的双向数据流。 164 | 165 | 2.消息:即HTTP的请求或响应消息,由一系列帧构成,会发送给TCP层。 166 | 167 | 3.帧:HTTP/2通信的最小单位,每个帧都包含帧头(会标识出当前帧所属的数据流)。 168 | 169 | 来自不同数据流的帧可以交错发送,然后再根据每个帧头的数据流标识符重新组装。即逻辑上看数据流是分别独立传输互不干扰,但其实一次传输中分属不同数据路的帧会一起传输。即一个通道中同时发送的有各个不同的数据流的帧,所以数据流也是个逻辑上的概念,它们的独立性靠每个帧头的数据流标识符来区分。 170 | 171 |  172 | 173 | ###### 4.HTTP/2的问题 174 | 175 | 1.对头阻塞(head of line blocking) 176 | 177 | HTTP2还是基于TCP协议的,TCP要保证传输过来的包是有序的。如果某个包在TCP层丢失了,那么后面的包都传不过来。因为TCP要保证包的顺序,会一直等丢失的包重传。只有顺序没问题了,才会向上传递给应用层。 178 | 179 | 所以有一个QUIC协议,可以解决这个问题,因为QUIC协议底层是基于UDP协议的。 180 | 181 |  182 | 183 | 2.握手延迟 184 | 185 | 还是因为底层是TCP,还有TLS建立一个信任的信道连接。 186 | 187 | RTT(Round Trip Time):往返延迟,可以简单理解为通信一来一回的时间。 188 | 189 | QUIC协议能实现0RTT的连接通信:因为底层是走UDP,不用多次握手建立连接,直接将数据发过去。 190 | 191 |  192 | 193 | ##### 3.HTTP3 194 | 195 | ###### 1.概述: 196 | 197 | Google仍觉得HTTP/2不够快,于是就有了HTTP/3,HTTP/3由Google开发,弃用TCP协议,改为使用基于UDP协议的QUIC协议实现。 198 | 199 | QUIC(Quick UDP Internet Connections)译为:快速UDP网络连接,由Google开发,于2018年从HTTP-Over-QUIC改为HTTP/3。 200 | 201 |  202 | 203 | ###### 2.HTTP/3疑问 204 | 205 | 1.HTTP/3基于UDP,如何保证可靠传输? 206 | 207 | 有QUIC协议层来保证,做了以前TCP的一部分工作保证可靠传输。 208 | 209 | 2.为何Google不开发一个新的不同于TCP,UDP的传输层协议呢? 210 | 211 | 目前世界上的网路设备基本只认识TCP,UDP。 212 | 213 | 如果要修改传输层,意味着操作系统的内核也要修改,比如Socket的一系列API。 214 | 215 | 这些情况也导致了,IETF标准化的许多TCP新特性都因缺乏广泛支持而没有得到广泛的部署和使用。 216 | 217 | 3.HTTP3还没有落地实现,成为一个标准,还在试验,测试阶段。 218 | 219 | ###### 3.HTTP/3的特性:连接迁移 220 | 221 |  222 | 223 | ###### 4.HTTP/3的问题 224 | 225 | 操作系统内核,CPU负载。 226 | 227 | 根据Google和Facebook称,与基于TLS的HTTP/2相比,它们大规模部署的QUIC需要近2倍的CPU使用量。 228 | 229 | 因为以前用的都是基于TCP协议的HTTP,所以操作系统,比如Linux内核的TCP部分有很好的优化,而UDP部分由于很少用到,所以没有得到像TCP那样的优化。而且大部分硬件对TCP和TLS都有加速,这个对于UDP基本没有。所以QUIC也没有得到这些优化。 -------------------------------------------------------------------------------- /13.其他协议和补充知识.md: -------------------------------------------------------------------------------- 1 | #### 13.其他协议 2 | 3 | ##### 1.ARP和RARP 4 | 5 | 1.ARP(Address Resolution Protocol),译为地址解析协议。 6 | 7 | 是网络层的一个协议,通过IP地址获取MAC地址。 8 | 9 | 2.RAPR(Reverse Address Resolution Protocol),译为逆地址解析协议。 10 | 11 | 使用与ARP相同的报头结构,作用与ARP相反,用于将MAC地址转换为IP地址。 12 | 13 | 后来被BOOTP,DHCP所取代。 14 | 15 | ##### 2.ICMP 16 | 17 | ICMP(Internet COntrol Message Protocol),译为互联网控制消息协议,网络层协议。 18 | 19 | IPV4中的ICMP被称作ICMPv4,IPv6中的ICMP则称作ICMPv6。 20 | 21 | 通常用于返回错误信息:比如TTL值过期,目的不可达。 22 | 23 | ICMP的错误消息总是包括乐源数据并返回给发送者。 24 | 25 | ##### 3.Socket: 26 | 27 | 是一套网络编程API,一般的操作系统都有,利用它可以建立网络连接。 28 | 29 | 开发人员平常发送的HTTP,FTP,SMTP等请求,底层都是通过调用SocketAPI来实现的。 30 | 31 | ##### 4.WebSocket协议 32 | 33 | 和Socket不同,WebSocket是一个协议。 34 | 35 | ###### 1.WebSocket由来 36 | 37 | HTTP请求是典型的请求应答模式,而且只能是客户端主动请求,服务器被动应答。服务器不能主动请求,通信只能由客户端发起。所以,早起很多网站为了实现 “推送” 技术,所用的技术都是轮询。表面上看起来是推送,实际上还是客户端主动请求。 38 | 39 | 轮询是指由浏览器每隔一段时间向服务器发出HTTP请求,然后服务器返回最新的数据给客户端。这样就很占用服务器的带宽,浪费资源。 40 | 41 | 为了更好地节省服务器资源和带宽,并且能够实时地进行通讯,HTML5规范中出现了WebSocket协议。 42 | 43 | 既然是HTML5规范,WebSocket协议一般用在浏览器,前端中。 44 | 45 |  46 | 47 | ###### 2.WebSocket是基于TCP的支持`全双工`通信的应用层协议。 48 | 49 | 客户端,服务器,任何一方都可以主动发消息给对方。 50 | 51 | WebSocket的应用场景很多:社交订阅,股票基金报价,体育实况更新,多媒体聊天,多玩家游戏等。 52 | 53 | ###### 3.HTTP和WebSocket对比 54 | 55 | 1.WebSocket和HTTP属于平级关系,都是应用层的协议。 56 | 57 | 其实TCP本身就是支持全双工通信的,客户端,服务端均可主动发消息给对方。所以如果我们不走HTTP协议,直接通过TCP通信,服务器端就可以主动推送消息给客户端。 58 | 59 | 只是HTTP设计之初就是“请求-应答模式”限制了TCP的全双工能力。 60 | 61 | 2.WebSocket使用80(ws://)、443(wss://)端口,兼容HTTP,协议号是ws://和wss://。可以绕过大多数防火墙的限制。 62 | 63 | 比如:ws://example.com/index.html 64 | 65 | 3.与HTTP不同的是,WebSocket需要在应用层建立连接 66 | 67 | HTTP需要在TCP协议层建立连接,然后应用层就不需要建立连接了。WebSocket就需要在应用层建立连接,这就使得WebSocket称为一种有状态的协议,之后通信时可以省略部分状态信息。 68 | 69 | 即建立了应用层的WebSocket连接后,两边就都知道对方的存在。以后发送消息时,就可以省略一些身份信息等。像以前HTTP要带着Cookie信息,告诉服务器我是谁。 70 | 71 | HTTP请求可能需要在每个请求都携带额外的状态信息,如身份认证等。 72 | 73 | ###### 4.借助HTTP协议来建立连接 74 | 75 | 由客户端(浏览器)主动发出握手请求 76 | 77 | 必须设置几个请求头 78 | 79 | Connection: Upgrade,表示客户端希望连接升级。 80 | 81 | Upgrade: websocket,表示希望升级到WebSocket协议。 82 | 83 | Sec-WebSocket-Version,表示支持的Websocket版本 84 | 85 | Sec-WebSocket-Key是客户端生成的随机字符串,服务器收到后,会进行一系列的算法得到另一串数字返回给客户端。客户端验证这串返回的数字,如果正确能匹配的上,那么确认这次请求是WebSocket协议。如此操作是为了尽量避免普通HTTP请求,被认为是WebSocket协议。 86 | 87 | ##### 5.WebService 88 | 89 | 1.译为Web服务,是一种跨编程语言和跨操作系统平台的远程调用技术标准。是一个比较落后的标准,因为这些跨编程语言,跨操作系统这些功能都可以直接通过Web API来实现,已经是默认实现的。 90 | 91 | WebService使用场景举例:天气预报,手机归属地查询,航班信息查询,物流信息查询等。比如天气预报,是气象局把自己的服务以WebService形式暴露出来,让第三方程序可以调用这些服务功能。 92 | 93 | 事实上,WebService完全可以用普通的WebAPI取代,比如HTTP+JSON,现在很多企业的开放平台都是直接采用Web API。 94 | 95 | 2.WebService核心概念 96 | 97 | SOAP(Simple Object Access Protocol),译为:简单对象访问协议。 98 | 99 | 很多时候,SOAP=HTTP+XML,WebService使用SOAP协议来封装传递数据。 100 | 101 | WSDL(Web Services Description Language),译为:Web服务描述语言。 102 | 103 | 是一个XML文档,用以描述WebService接口的细节,比如参数,返回值等。 104 | 105 | 一般在WebService的URL后面跟上?wsdl获取WSDL信息,比如: 106 | 107 | http://ws.webxml.com.cn/WebServuce/WeatherWS.asmx?wsdl 108 | 109 | 3.现在很多公司开放数据都不会这么做,而是普通的WebAPI+JSON。 110 | 111 | ##### 6.RESTful简介 112 | 113 | ###### 1.概述 114 | 115 | 1.REST的全程是: REpresentational State Transfer,译为“表现层状态转移” 116 | 117 | 2.REST是一种互联网软件架构设计风格: 118 | 119 | 定义了一组用于创建Web服务的约束,比如请求该怎么发 120 | 121 | 符合REST架构的Web服务,称为RESTful Web服务。 122 | 123 | ###### 2.RESTful实践建议 124 | 125 | 1.URL中尽量使用名词(建议用复数形式),不使用动词 126 | 127 | 推荐:/users, /users/6 128 | 129 | 不推荐:/listUsers,/getUser?id=6,/user/list,/user/get?id=6 130 | 131 | 2.使用HTTP的方法表达动作 132 | 133 | URL很简单,可以根据不同的请求方式,确定这个请求URL有不同的动作含义。 134 | 135 | 3.一个资源连接到其他资源,使用子资源的形式 136 | 137 | GET /users/6/cars/88 138 | 139 | POST /users/8/cars 140 | 141 | 4.API版本化:URL携带版本 142 | 143 | mj.com/v1/users 144 | 145 | mj.com/v2/users/66 146 | 147 | 5.返回JSON格式的数据 148 | 149 | 6.发生错误时,不要反回200状态码。 150 | 151 | ##### 7.HTTPDNS 152 | 153 | 1.HTTPDNS是基于HTTP协议向DNS服务器发送域名解析请求,替代了基于DNS协议向运营商Local DNS发起解析请求的传统方式。可以避免Local DNS造成的域名劫持和跨网访问问题,常用在移动互联网中,比如Android,IOS开发中。 154 | 155 | 2.HTTPDNS-使用 156 | 157 | 市面上已经有现成的解决方案了: 158 | 159 | 腾讯云:https://cloud.tencent.com/product/httpdns 160 | 161 | 阿里云:https://help.aliyun.com/product/30100.html 162 | 163 | 移动端再集成相关的SDK即可使用HTTPDNS服务。 164 | 165 | ##### 8.FTP(File Transport Protocol) 166 | 167 | 1.译为:文件传输协议。是基于TCP的应用层协议。 168 | 169 | FTP的URL格式为:ftp://[user[:password]@]host[:port]/url-path 170 | 171 |  172 | 173 | 在传输大文件方面,HTTP协议不适合,所以不用HTTP服务器,而是用FTP服务器,专门针对文件上传和下载。 174 | 175 | 2.FTP:连接模式 176 | 177 | FTP有2种连接模式:主动Active和被动Passive 178 | 179 | 不管是哪种模式,都需要客户端和服务器建立2个连接: 180 | 181 | 1.控制连接:用于传输状态信息(命令,cmd) 182 | 183 | 2.数据连接:用于传输文件和目录信息(data) 184 | 185 |  186 | 187 | 3.主动连接模式 188 | 189 |  190 | 191 | 4.被动连接模式 192 | 193 |  194 | 195 | ##### 9.邮件相关的协议 196 | 197 |  198 | 199 | 1.收发邮件过程 200 | 201 |  202 | 203 | 2.POS和IMAP 204 | 205 |  206 | 207 | #### 14.补充知识 208 | 209 | ##### 1.VPN 210 | 211 | ###### 1.概述 212 | 213 | VPN(Virtual Private Network),译为:虚拟私人网络。它可以在公共网络上家里专用网络,进行加密通讯。即原来是用来安全上网的,现在也被用来科学上网。 214 | 215 |  216 | 217 | ###### 2.VPN作用 218 | 219 | 提高上网的安全性 220 | 221 | 保护公司内部资料:公司内部架设一台VPN服务器 222 | 223 | 隐藏上网者的身份:最后暴露的是VPN服务器的IP 224 | 225 | 突破网站的地域限制:有些网站针对不同地区的用户展示不同的内容 226 | 227 | 突破网络封锁: 228 | 229 | 因为有GWF的限制,有些网站在国内上不了。Great Firewall of China:中国长城防火墙。 230 | 231 | 购买能够访问这些网站的VPN服务器 232 | 233 | ###### 3.VPN和代理的区别 234 | 235 | 软件:VPN一般需要安装VPN客户端软件,代理不需要安装额外的软件 236 | 237 | 安全性:VPN默认会对数据进行加密,代理默认不会对数据进行加密。(数据最终是否加密取决于使用的协议本身) 238 | 239 | 费用:一般情况下,VPN比代理贵。 240 | 241 | ###### 4.VPN的原理 242 | 243 |  244 | 245 | 这些协议一般工作在传输层和数据链路层:能修改从应用层传下来的数据。 246 | 247 | ##### 2.tcpdump 248 | 249 | 一个Linux平台的抓包工具,命令行界面。 250 | 251 |  252 | 253 | ##### 3.网络爬虫 254 | 255 | 1.网络爬虫(Web Crawler),也叫做网络蜘蛛(Web Spider)。 256 | 257 | 模拟人类使用浏览器操作页面的行为,对页面进行相关的操作。 258 | 259 | 常用爬虫工具:Python的Scrapy框架。 260 | 261 | 2.网络爬虫-简易实例: 262 | 263 | 可以使用Java的一个小框架Jsoup爬一些简单的数据 264 | 265 | jar包:https://jsoup.org/packages/jsoup-1.13.1.jar 266 | 267 | https://mirror.bit.edu.cn/apache//commons/io/binaries/commons-io-2.8.0-bin.zip 268 | 269 | 爬取目标:https://ext.se.360.cn ,江湖推荐,良心推荐部分的图标。 270 | 271 |  272 | 273 | 代码: 274 | 275 | ```java 276 | package com.mj; 277 | 278 | import org.apache.commons.io.FileUtils; 279 | import org.jsoup.Jsoup; 280 | import org.jsoup.nodes.Document; 281 | import org.jsoup.nodes.Element; 282 | import org.jsoup.select.Elements; 283 | 284 | import java.io.File; 285 | import java.net.URL; 286 | 287 | /** 288 | * 描述: 289 | * 290 | * @author txl 291 | * @date 2021-03-23 10:02 292 | */ 293 | public class Main { 294 | public static void main(String[] args) throws Exception { 295 | //请求网站:https://ext.se.360.cn 296 | String dir = "D:/txl/imgs/"; 297 | String url = "https://ext.se.360.cn"; 298 | Document document = Jsoup.connect(url).get();//得到html页面 299 | Elements elements = document.select(".recommend .appwrap"); 300 | for (Element element : elements) { 301 | String img = element.selectFirst("img").attr("src"); 302 | String title = element.selectFirst("h3").text(); 303 | String intro = element.selectFirst(".intro").text(); 304 | System.out.println(img + "--" + title + "--" +intro); 305 | 306 | String filepath = dir + (title + ".png"); 307 | FileUtils.copyURLToFile(new URL(img), new File(filepath)); 308 | } 309 | } 310 | } 311 | ``` 312 | 313 | 爬取效果: 314 | 315 |  316 | 317 | 3.robots.txt 318 | 319 | robots.txt是存放于网站根目录下的文本文件,比如https://www.baidu.com/robots.txt 320 | 321 | 用来告诉爬虫:哪些内容是不应该被爬取,哪些是可以被爬取的。 322 | 323 | 因为一些系统中的URL是大小写敏感的,所以robots.txt的文件名应统一为小写。 324 | 325 | 他并不是一个规范,只是约定俗成的,所以并不能保证网站的隐私。 326 | 327 | 只能防君子,不能防小人,无法阻止不讲“武德”的年轻爬虫爬取隐私数据。 328 | 329 |  330 | 331 | ##### 4.HTTP缓存 332 | 333 | Cache的发音跟Cash(现金)一样。 334 | 335 | 通常会缓存的情况是:GET请求+静态资源(比如HTML,CSS,JS,图片等) 336 | 337 | Ctrl + F5:可以强制刷新缓存。 338 | 339 | ###### 1.缓存-响应头 340 | 341 |  342 | 343 | ###### 2.理解一个大概的机制 344 | 345 | 浏览器第一次请求得到的数据,通常会将一些静态资源缓存到本地,内存中或者磁盘中,并且响应头中会有这些缓存的过期时间。 346 | 347 | 在过期时间之内,浏览器再次请求这些数据时会直接从本地缓存获取。当过期时间结束,缓存过期时,浏览器再次请求这些数据,服务器收到请求后,并不会立马将资源返回给客户端。而是先从请求头的一些信息中判断这次请求的资源有没有变化,如果没有变化,那么会返回给客户端一个:304 Not Modified状态码。告诉浏览器这次请求的资源没有变化,可以直接从缓存中获取,并且刷新缓存时间。 348 | 349 | 304 Not Modified:说明无需再次传输请求的内容,也就是说可以使用缓存的内容。 350 | 351 | 客户端会缓存一些静态资源,比如HTML页面。 352 | 353 | 服务器发现客户端这次请求的内容我上一次已经给过你了,而且这次请求的内容在我的服务器这边根本就没有动过。`服务器端就会返回一个304状态码给客户端,和一些常规的响应头,不返回请求的资源了。`告诉客户端这次响应的内容,我就不响应给你了,你直接从自己的缓存中拿吧。 354 | 355 | ###### 3.Cache-Cotril: no-cache 356 | 357 | 表示每次都要发请求给服务器询问缓存是否有变化,如果没有变化,那么服务器换返回304 Not Modified状态码,可以直接使用缓存的内容。如果有变化,那么必须从服务器请求新的数据。 358 | 359 | ###### 4.缓存-请求头 360 | 361 | if-None-Match 362 | 363 | 如果上一次的响应头中有Etag,就会将Etag的值作为请求头的值。 364 | 365 | 如果服务器发现资源的最新摘要值跟if-None-Match不匹配,就会返回新的资源(200 OK) 366 | 367 | 否则,就不会返回资源的具体数据(304 Not Modified),告诉浏览器直接从缓存拿 368 | 369 | if-Modified-Since 370 | 371 | 如果上一次的响应头中没有Etag,有Last-Modified,就会将Last-Modified的值作为这个请求头的值 372 | 373 | 如果服务器发现资源的最后一次修改时间晚于If-Modified-Since,就会返回新的资源(200 OK) 374 | 375 | 否则,就不会返回资源的具体数据(304 Not Modified) 376 | 377 | ###### 5.Last-Modified和ETag对比 378 | 379 | Last-Modified的缺陷: 380 | 381 | 1.只能精确到秒级别,如果资源在1秒内被修改了,客户端将无法获取最新的资源数据。 382 | 383 | 2.如果某些资源被修改了,但是内容却没有变化。比如删掉一个字符,又加上这个字符,那么最后一个修改时间会更新,但是内容却没有变化。 384 | 385 | 导致相同数据重复传输,应该使用缓存时没有使用缓存。 386 | 387 | ETag可以克服这些缺点 388 | 389 | 1.只要资源的内容发生变化,ETag的值就会变化。 390 | 391 | `所以ETag的优先级高于Last-Modified。` 392 | 393 | ###### 6.缓存的使用流程 394 | 395 |  396 | 397 | ##### 5.IPV6 398 | 399 |  400 | 401 | IPV6的地址格式 402 | 403 |  404 | 405 | IPV6首部格式 406 | 407 |  -------------------------------------------------------------------------------- /2.路由和其他概念.md: -------------------------------------------------------------------------------- 1 | ## 路由 2 | 3 | - 在不同网段之间转发数据,需要有路由器的支持 4 | 5 | - 默认情况下,路由器只知道跟它直连的网段,非直连的网段需要通过静态路由,动态路由告诉它。 6 | 7 | - 1. 静态路由 8 | 9 | 管理员手动添加路由信息 10 | 11 | 适用于小规模网络 12 | 13 | 2. 动态路由 14 | 15 | 路由器通过路由选择协议(比如RIP,OSPF)自动获取路由信息 16 | 17 | 适用于大规模网络 18 | 19 | ### 1.练习1:如何让4台主机之间可以互相通信 20 | 21 |  22 | 23 | - 1.默认情况下,路由器只知道跟它直连的网段:所以计算机0和计算机1能通信;计算机2和计算机3能通信。 24 | - 2.中间连接两个路由器的部分应该怎么设置? 25 | - 3.尝试ping一下计算机0和计算机3: 26 | 27 |  28 | 29 | ping不通,因为计算机0和计算机3不是直连在一个路由上。 30 | 31 | 注意:是路由网关192.168.1.1返回的消息,目的主机无法到达。因为路由器直接发现目的地,不是直连在该路由上,无法到达,所以返回给源主机该信息。 32 | 33 | ### 2.通过配置静态路由使计算机0和计算机3进行通信 34 | 35 | 1.打开路由8进行配置: 36 | 37 |  38 | 39 | 40 | 41 | 2.路由0和路由1之间通过Serial2/0连接:互相连接的路由要为串口配置ip地址,而且ip地址要在一个网段。 42 | 43 |  44 | 45 | 3.配置静态路由:当计算机0的目的地址是193.169.2.10时,走到路由器0。路由器0在路由表中进行匹配,路由表中存在静态路由。发现要先通过194.170.1.1找到路由器2,才能到193.169.2网段。 46 | 47 |  48 | 49 | 50 | 51 | 4.查看路由表 52 | 53 |  54 | 55 |  56 | 57 | 58 | 59 | 路由器0目前知道5个网段该怎么走: 60 | 192.168.1.0; 61 | 192.168.2.0; 62 | 193.169.1.0; 63 | 193.169.2.0; 64 | 194.170.1.0; 65 | 66 | 5.同理:路由器1要先通过194.170.1.1找到路由器0,再返回响应给计算机0 67 | 68 |  69 | 70 | 6.路由表不配置网段,只配置一个特定的ip。 71 | 72 |  73 | 74 | 在路由器1中,配置了一个路由。目的地址是192.168.2.10且子网掩码是255.255.255.255。说明只匹配一个ip地址,而不是网段。 75 | 或者说在192.168.2.0这个网段中,路由1只能找到192.168.2.10这个ip,其他ip找不到。 76 | 77 |  78 | 79 | 7.默认路由:没有在路由表中指定的,就走默认路由。 80 | 81 |  82 | 83 |  84 | 85 | ### 3.公网和私网 86 | 87 | * IP地址也可以分为:公网ip和私网ip 88 | 89 | 1.公网ip(Public) 90 | 91 | 1.Internet上的路由器只有到达公网的路由表,没有到达私网的路由表。 92 | 93 | 2.公网ip由因特网信息中心(Inter NIC)统一分配和管理。 94 | 95 | 3.ISP(移动,电信...)需要向Inter NIC申请公网IP。 96 | 97 | 2.私网IP(Private) 98 | 99 | 1.主要用于局域网,下面是保留的私网网段 100 | 101 | A类:10.0.0.0/8,一个A类网络 102 | 103 | B类:172.16.0.0/16 ~ 172.31.0.0/16,16个B类网络。 104 | 105 | C类:192.168.0.0/24 ~192.168.255.0/24,256个C类网络 106 | 107 | * 重点:因特网中的路由器默认是无法知道私网ip的,无法通信。那么我们平常上网是如何连接到外网的呢? 108 | 109 | * 私网ip给因特网中的一个公网ip发送请求时:源私网ip地址,会被因特网中的路由器转换成一个公网ip地址。这也成为NAT转换。 110 | 111 | ### 4.NAT 112 | 113 | Network Address Translation 114 | 115 | 网络地址转换技术: 116 | 117 | 主要用于实现位于内部网络的主机访问外部网络的功能。当局域网内的主机需要访问外部网络时,通过NAT技术可以将其私网地址转换为公网地址,并且多个私网用户可以共用一个公网地址,这样既可以保证网络互通,又节省了公网地址。 118 | 119 | 企业或家庭所使用的网络为私网,使用的是私网地址; 120 | 121 | 运营商维护的网络为公共网络,使用的是共有地址。 122 | 123 | 会隐藏内部真实IP。 124 | 125 | **私有地址不能在公网中路由,此时需要用到NAT技术进行地址转换(一般经过多个路由,进行多次转换)。** 126 | 127 | 128 | 129 | * NAT分类: 130 | 131 | * 1.静态转换: 132 | 133 | 手动配置NAT映射表 134 | 135 | 一对一转换 136 | 137 | 不能达到节约公网的目的 138 | 139 | * 2.动态转换 140 | 141 | 定义外部地址池,动态 142 | 143 | * PAT:Port Address Translation 144 | 145 | * 目前应用最广范的NAT实现方式。 146 | * 多对一转换,最大限度节约公网IP资源。 147 | * 采用端口多路复用方式,通过端口号标识不同的数据流。 148 | 149 | 150 | 151 | ### 5.第一个包会丢失 152 | 153 |  154 | 155 | 1.ping两个不同网段的ip地址时,会出现第一个包丢失的问题。 156 | 157 | * 过程 158 | 159 | 1.计算机1发送目的地址是不同网段的,那么会给网关发一个ARP广播。 160 | 161 | 告诉计算机1网关的MAC地址什么。 162 | 163 |  164 | 165 | 2.网关将自身的MAC地址通过ARP返回给计算机1 166 | 167 |  168 | 169 | 3.计算机1收到网关的MAC地址,先通过ICMP协议发送数据包发到网关192.168.1.1 170 | 171 | 注意这个ICMP协议包的目的地址其实是192.168.2.10,目标MAC地址是网关192.168.1.1的MAC地址。 172 | 173 |  174 | 175 | 4.计算机1把数据包发给网关的时候,路由器发现这个数据是给192.168.2.10的。 176 | 177 |  178 | 179 | 但是路由器第一次不知道这个ip的MAC地址,所以不能直接将ICMP协议包发给目的ip。**所以路由器会把ICMA包丢掉。**因为忙不过来,要先发ARP找到目的MAC。 180 | 181 |  182 | 183 | 然后发一个ARP,寻找192.168.2.10的MAC地址。 184 | 185 |  186 | 187 | 5.之后路由就会缓存192.168.2.10的MAC地址。 188 | 189 | 6.小结:在第一次跨网段通信时,计算机1判断目标地址不在同一个网段。那么要通过路由网关来实现跨网段通信。会先发一个ARP给路由,获得网关的MAC。然后知道网关MAC后,会将ICMP包携带着目标ip,网关mac发给网关。网关第一次也没有目标ip的mac,所以也要先发一个arp找到目标mac,缓存下来。但是路由忙不过来,就会丢掉计算机1发的icmp包,而去发arp包获得目的ip的mac。 190 | 191 | 这样第一次跨网段通信就会产生第一次包丢失问题,后续就建立好正常通信了。 192 | 193 | -------------------------------------------------------------------------------- /3.物理层和数据链路层.md: -------------------------------------------------------------------------------- 1 | ### 1.网络互联模型 2 | 3 | 为了更好地促进互联网的研究和发展,国际标准化组织ISO在1985年制定了网络互连模型。 4 | 5 | 1.OSI参考模型,具有7层结构:偏理论 6 | 7 | 2.TCP/IP协议模型:实际应用中用的最多,偏实际。 8 | 9 | 所以TCP/IP是一种网络互连模型的名称。 10 | 11 |  12 | 13 | 3.为了方便学习,一些教材会出现5层结构。因为数据链路层和物理层很值得单独学习。 14 | 15 |  16 | 17 | 4.大致的请求过程 18 | 19 |  20 | 21 | 22 | 23 | 应用层数据:报文,用户数据 24 | 25 | 经过运输层包装:段 26 | 27 | 经过网络层包装:包 28 | 29 | 经过数据链路层包装:帧 30 | 31 | 经过物理层包装:比特流 32 | 33 |  34 | 35 | ### 2.物理层(Physical) 36 | 37 | 1. 物理层定义了接口标准,线缆标准,传输标准,传输方式等。 38 | 39 |  40 | 41 | 2. 物理层数据 42 | 43 |  44 | 45 | ### 3.一些物理层相关概念 46 | 47 | 1.模拟信号 48 | 49 | 连续的信号,适合长距离传输 50 | 51 | 抗干扰能力差,收到干扰时表型变形很难纠正。 52 | 53 | 2.数字信号 54 | 55 | 离散的信号,不适合长距离传输 56 | 57 | 抗干扰能力强,受到干扰时波形失真可以修复。 58 | 59 | 3.数据通信模型 60 | 61 |  62 | 63 | 电话线不能传输数字信号,所以要用 猫 将数字信号转成模拟信号。 64 | 65 | 4.信道 66 | 67 | 信道:信息传输的通道,一条传输介质上(比如网线)上可以有多条信道 68 | 69 | 单工通信:有A,B两端进行通讯。信号只能往一个方向传输,任何时候都不能改变信号的传输方向。比如无线电广播,有限电视广播。 70 | 71 | 半双工通信:信号可以双向传输,但是A,B两端必须交替进行,同一时间只能往一个方向传输。比如对讲机。 72 | 73 | 全双工通信:信号可以同时双向传输。比如手机(打电话,听说同时进行) 74 | 75 | ### 4.数据链路层:Data Link 76 | 77 | 1.不同类型的数据链路,在数据链路层所用的通信协议可能是不同的。 78 | 79 | 1.广播信道:CSMA/CD协议。 80 | 81 | 2.点对点信道:PPP协议。 82 | 83 | 数据链路层的数据:帧。 84 | 85 | 1.链路:从一个节点到相邻节点的一段物理线路(有线或无线),中间没有其他交换节点。 86 | 87 |  88 | 89 | 2.数据链路:**在一条链路上传输数据时,需要有对应的通信协议来控制数据的传输。** 90 | 91 | 不同类型的数据链路,在**数据链路层**所用的通信协议可能是不同的: 92 | 93 | 1.广播信道:CSMA/CD协议(广播信道:比如同轴电缆,集线器组成的网络) 94 | 95 | 2.点对点信道:PPP协议(比如两个路由器之间的信道) 96 | 97 | 98 | 99 | 3.数据链路层的3个基本问题 100 | 101 | 1.封装成帧:把来自网络层的数据包封装成数据帧。 102 | 103 |  104 | 105 | 2.透明传输 106 | 107 | 帧在传输介质上传输的时候,是一连串的多个帧进行传输的。那么怎么区分那一部分是 一个完整的帧呢? 108 | 109 | 数据链路层在包装来自网络层的数据包时,会在帧两头加上帧首部(SOH)和帧尾部 (EOT)。但是这又会出现新的问题,如果帧的数据部分出现了SOH/EOT,这就产生冲突。导致得到一段残缺的帧。 110 | 111 |  112 | 113 | 解决:透明传输 114 | 115 | 数据部分一旦出现SOH/EOT/ESC,就需要转义。加上ESC进行转义。 116 | 117 |  118 | 119 | 3.差错检验 120 | 121 | 考虑到帧在链路上传输时可能会发生差错,那么就有一个差错检验机制。 122 | 123 |  124 | 125 | FCS是根据帧数据部分和数据链路层首部计算出来的。 126 | 127 | 目的端接收到数据后,再次进行一次计算得到FCS和帧尾部的FCS进行比较,如果出错,就丢掉该数据。 128 | 129 | 130 | 131 | ### 5.CSMA/CD协议: 132 | 133 | 1.不同类型的数据链路,在数据链路层所用的通信协议可能是不同的。 134 | 135 | 1.广播信道:CSMA/CD协议。 136 | 137 | 2.点对点信道:PPP协议。 138 | 139 | 140 | 141 | 1. 载波侦听多路访问/冲突检测 142 | 143 | 例如集线器组成的网络,是半双工通信的,同一时间只能往一个方向传输。 144 | 145 | 载波侦听:某一端会监听线路上是否有信号在传输,有的话就不发数据;没有的话,才发。 146 | 147 | 多路访问:各个端都可以发送信号。 148 | 149 | 冲突检测:如果两个端(计算机)同时检测线路上没有信号在传输,那么就会都发信号。但是此时由于是半双工通信,就会发生冲突。信号发生冲突,就会往回弹。所以计算机要能判断出收到的信号是来自其他端直接发送的还是因为冲突弹回来的。 150 | 151 | 152 | 153 | 2.使用了CSMA/CD的网络可以称为是 以太网,他传输的以太帧。比如集线器,交换机组成的网络。(局域网) 154 | 155 | 以太网帧的格式有:Ethernet V2标准, IEEE的802.3标准。 156 | 157 | 使用最多的是:Ethernet V2标准。 158 | 159 | 3.用交换机组建的网络,已经支持全双工通信。不需要再使用CSMA/CD协议,但它传输的帧依然是以太网帧。 160 | 161 | 所以用交换机组建的网络仍然可以叫做以太网。 162 | 163 |  164 | 165 | 4.为了能够检测正在发送的帧是否产生了冲突,以太网的帧`至少`要64字节。 166 | 167 | 以太帧一般是传输信道的2倍,这样发生冲突时,信号会回弹。弹回到发出点时,会发现该信号还在发送(因为是信道的2倍)。那么就可以认定该信号发生了冲突。 168 | 169 | 170 | 171 | ### 6.Ethernet V2帧的格式 172 | 173 | 1. Ethernet V2帧的格式:不需要帧开始符和帧结束符。 174 | 175 | 那么接收帧时,怎么判断帧结束怎么判断帧开始呢? 176 | 177 | 以太网使用曼切斯特编码。接收端接收帧过程只要发现没有信号跳变,就认为帧结束。 178 | 179 | 2. 帧在传到物理层时,会在帧起始位置加上前同步码和帧开始定界符,一共8字节。 180 | 181 |  182 | 183 | 3. 首部:目标MAC+源MAC+网络类型(IPV4/IPV6) 184 | 185 | 以太网帧:首部+`数据(网络层传过来的IP数据包)`+FCS 186 | 187 | 数据部分的长度至少是:64-6-6-2-4=46字节,最多是1500字节 188 | 189 | 4. 当数据部分的长度小于46个字节时,数据链路层会在数据的后面加入一些字节填充,当接收端接收时又会将填充的部分去掉。 190 | 191 |  192 | 193 | 5. 长度总结: 194 | 195 | 以太网帧的数据长度:46~1500字节 196 | 197 | 以太网帧的长度:64~1518字节 198 | 199 | 6. 数据链路层为网络层传下来的数据包添加的内容: 200 | 201 |  202 | 203 | 目标MAC+源MAC+网络类型+FCS。 204 | 205 | ### 7.PPP协议: 206 | 207 | 1. 不同类型的数据链路,在数据链路层所用的通信协议可能是不同的。 208 | 209 | 1.广播信道:CSMA/CD协议。 210 | 211 | 在广播信道中,数据是会传输给各个端的,所以需要源MAC和目标MAC来确保接收端和发送端。 212 | 213 | 2.点对点信道:PPP协议,两个路由之间的链路。 214 | 215 | 点对点信道中,数据传输的两端是确定的,所以不需要源MAC和目标MAC。 216 | 217 | 2. 一些PPP帧的特点: 218 | 219 | 1.因为是点对点通信,所以两端是确定的,顺着链路方向只能到达确定的一端。所以不需要源MAC地址和目标MAC地址。 220 | 221 |  222 | 223 | 2.PPP帧和以太网帧是不一样的,但数据部分都是相同的,都是从IP层传下来的。 224 | 225 | 3.如果俩个路由器之间有一个交换机,那么路由器和交换机传输的就是以太网帧,有源目的MAC的。 226 | 227 |  228 | 229 | 230 | 231 | ### 8.网卡 232 | 233 | 1.网卡工作在物理层和数据链路层。 234 | 235 |  236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | -------------------------------------------------------------------------------- /4.网络层.md: -------------------------------------------------------------------------------- 1 | ### 4.网络层 2 | 3 | 1.网络数据包(IP数据包,Packet)由首部,数据2部分组成 4 | 5 | 2.数据部分:很多时候是由传输层传递下来的数据段(Segment) 6 | 7 |  8 | 9 | #### 1.网络层首部:由两部分组成。 10 | 11 | ##### 1.固定部分:固定20个字节 12 | 13 | 1.版本(Version):占4位 14 | 15 | 0b0100:IPV4 16 | 17 | 0b0110:IPV6 18 | 19 | 2.首部长度(Header Length):占4位,二进制乘以4才是最终长度 20 | 21 | 最小值:0b0101,对应的十进制值是5,所以最终首部长度最小是5*4=20字节 22 | 23 | 最大值:0b1111,对应的十进制值是15,所以最终首部长度最大时15*4=60字节。 24 | 25 | 由于首部固定长度是20字节,所以可变长度是0~40字节。 26 | 27 |  28 | 29 | 3.总长度:Total Length 30 | 31 | 占16位 32 | 33 | 1.首部+数据部分的长度之和,即整个数据包的长度,最大值是65535字节。 34 | 35 | 2.整个数据包是要传给数据链路层作为帧的数据部分的,但是帧的数据部分不能超过1500字节,所以过大的IP数据包,会被分成片(fragments)传输给数据链路层。 36 | 37 | 而且每一片fragments都有自己的网络层首部(IP首部)。 38 | 39 |  40 | 41 | 4.区分服务:Differentiated Services Field 42 | 43 | 1.占8位,可以用来提高网络的服务质量,Quality of Service 44 | 45 | 2.没有值时:0x00;如果值是0x40,可能路由器就会优先传输这个给IP包,即提高网络服务质量。 46 | 47 | 5.标识(Identification): 48 | 49 | 1.占16位,数据包的ID,当数据包传给数据链路层时,发现数据包过大,数据包就会进行分片。每一片fragments都有自己的IP首部,而且这些片的IP首部的标识部分都一样。这样就能区分哪些片是一个IP包拆分的。 50 | 51 | 2.数据包的ID:代表是哪个IP包。而且有一个计数器专门管理数据包的ID,没发出一个数据包,ID就加1。 52 | 53 | 3.这个时候虽然能确定下来片fragments属于哪个数据包,但是怎么确定哪个片属于数据包的哪个部分呢? 54 | 55 | 6.片偏移(Fragment Offset) 56 | 57 |  58 | 59 | 1.占13位,片偏移乘以8:字节偏移,每一片的长度一定是8的整数倍。 60 | 61 | 2.字节偏移: 62 | 63 | 第一片:从IP数据包首部后的第0字节处开始算,共1400字节 64 | 65 | 第二片:从IP数据包首部后的第1400字节处开始算,共1400字节。 66 | 67 | 第三片:从IP数据包首部后的第2800字节处开始算,共1000字节。 68 | 69 | 所以第一片的字节偏移是0,其IP首部中片偏移就是0/8=0 70 | 71 | 第二片的字节偏移是1400,其IP首部中片偏移就是1400/8=175 72 | 73 | 第三片的字节偏移是2800,其IP首部中片偏移就是2800/8=350 74 | 75 | 3.为什么不直接用字节偏移呢,而是要再除以8,用片偏移呢? 76 | 77 | 因为存放偏移量的这部分一共才13位,最大值是8192-1=8191。而整个IP数据包的最大长度是65535字节。所以如果用字节偏移量的话,很可能13位不够表示。 78 | 79 | 7.标志(Flags) 80 | 81 | 1.占3位,每一位有不同的含义。 82 | 83 | 2.第一位(Reserved Bit):保留位 84 | 85 | 3.第二位(Don't Fragment):1代表不允许分片,0代表允许分片 86 | 87 | 4.第三位(More Fragments):1代表不是最后一片,0代表最后一片。 88 | 89 | 一旦发现第三位是0,说明这个网络层的数据包已经组装好了。 90 | 91 |  92 | 93 | 8.协议和首部检验和 94 | 95 | 网络层的数据是从运输层传下来的,那么`运输层用的什么协议`会被记录下来,放在网络层首部的协议位置处。 96 | 97 | 另外,ICMP也有协议字段,但是这些协议是被划分到网络层的。 98 | 99 | 100 | 101 | 传输层的TCP协议的数据,或者UDP协议的数据,都会传输给网络层,被打包成IP协议的数据。 102 | 103 |  104 | 105 | 9.生存时间:Time To Live, TTL 106 | 107 | 占8位 108 | 109 | 1.每个路由器在转发之前都会将TTL减1,一旦发现TTL减为0,路由器会返回错误报告。 110 | 111 | 2.各个操作系统的发送数据的默认TTL。 112 | 113 |  114 | 115 |  116 | 117 | 所以百度服务器应该是部署在linux服务器上,所以中间经历了64-52=12个服务器。 118 | 119 | 3.ping baidu.com -i 1 120 | 121 | 设置ping的数据的TTL是1,那么经过第一个路由器时就会减成0,就不会往下再发送包,而是返回报错信息。 122 | 123 | 我得ip:192.168.43.143。所以我的第一个网关地址就是192.168.43.1: 124 | 125 |  126 | 127 | 128 | 129 | ##### 2.工作在网络层的协议 130 | 131 | ARP,IPV4/IPV6,ICMP。 132 | 133 | 传输层的TCP协议的数据,或者UDP协议的数据,都会传输给网络层,被打包成IP(IPV4、IPV6)协议的数据。 134 | 135 | 1.网络数据包的数据部分很多时候就是由传输层传递下来的数据段。但是这个不是绝对的,因为有时候的传输过程没有用到应用层,传输层等。 136 | 137 | 比如发送一个ICMP包,ICMP协议是专门工作在网络层的协议。直接在网络层组织一个ICMP包,发送给接收端,此时网络数据包的数据部分就不是来自传输层了。 138 | 139 | 2.ARP虽然更贴近数据链路层,ICMP协议在网络层上,但都划到了网络层。 140 | 141 | #### 2.ping的几个用法: 142 | 143 | ping发的是ICMP协议数据 144 | 145 | 1.ping /?:查看ping的用法 146 | 147 | 2.ping ip地址 -l 数据包大小:发送指定大小的数据包 148 | 149 | 3.ping ip地址 -f:不允许网络分层。 150 | 151 | 4.ping ip地址 -i TTL:设置TTL的值 152 | 153 | 5.通过tracert,pathping命令,可以跟踪数据包经过了哪些路由器。 154 | 155 | tracert baidu.com 156 | 157 | pathping baidu.com 158 | 159 | #### 3.ping bilibili.com -l 4000 160 | 161 | ping 4000个字节的包给B站,看一下包分。 162 | 163 |  164 | 165 | 1.发了4次包,每次4000字节。 166 | 167 | 2.因为IP包是要传给数据链路层的,而数据链路层的数据部分不能超过1500字节。所以这个4000字节的IP包要分片。 168 | 169 | 3.那么就是这个包要分三片,发现这3片的IP网络层首部的表示部分Identification都是12025,所以这三篇属于同一个包。 170 | 171 | 4.这里的Fragment Offset部分是乘以8之后的结果。 172 | 173 |  -------------------------------------------------------------------------------- /5.传输层.md: -------------------------------------------------------------------------------- 1 | ### 1.传输层Transport 2 | 3 | 1.传输层的TCP协议的数据,或者UDP协议的数据,都会传输给网络层,被打包成IP(IPV4、IPV6)协议的数据。 4 | 5 | 2.传输层主要有两个协议: 6 | 7 | 1.TCP(Transimission Control Proticol),传输控制协议 8 | 9 | 如果之前的数据没有发送成功,还会再发送一次,那么就打乱了实时性(现在接收的信息,突然插入一个之前的信息)。 10 | 11 | 2.UDP(User Datagram Protocol),用户数据报协议。 12 | 13 | 如果之前的数据没有成功发过来,那我也不要了,我只关注当前的信息:音视频通话。 14 | 15 | 16 | 17 | 3.两个协议的大致区别: 18 | 19 |  20 | 21 | 22 | 23 | 4.我们一般发送一个请求,是先在应用层用一个协议封装一个数据,然后在发给下一层,即传输层。 24 | 25 | TCP协议一般封装的是,来自应用层的HTTP/HTTPS等协议封装的数据 26 | 27 | UDP协议一般封装的是,来自应用层的DNS协议封装的数据。 28 | 29 | 30 | 31 | #### 1.UDP-数据格式 32 | 33 | 1.UDP是无连接的,减少了建立和释放连接的开销 34 | 35 | 2.UDP尽最大可能交付传输的数据,但是不保证数据的完整性,即不保证可靠交付。 36 | 37 | 3.因此不需要维护一些复杂的参数,首部只有8个字节。(TCP首部至少20个字节) 38 | 39 |  40 | 41 | #### 2.UDP首部的构成: 42 | 43 | 1.UDP长度 44 | 45 | 16位,2字节:表示首部的长度+数据的长度 46 | 47 | 2.UDP校验和 Checksum 48 | 49 | 检验和的计算部分:伪首部+首部+数据 50 | 51 | 伪首部:仅在计算检验和时起作用,并不会传递给网络层。 52 | 53 |  54 | 55 | 3.端口Port 56 | 57 | 1.服务器可以在一个端口上开启一个服务器软件,这个服务器软件来监听发送到这个端口的数据。之后服务器软件再从8080端口将数据返回给客户端。 58 | 59 | 2.UDP首部中每个端口部分占用2字节,可以推测出端口号的取值范围0~65535。 60 | 61 | 3.客户端的源端口是应用软件发送请求时的端口,而且是临时开启的随机端口,不固定。 62 | 63 | 临时开一个端口发数据,所以同一个应用软件前后两次发数据时,源端口很可能是不一样的。 64 | 65 | 4.服务响应请求,返回数据时。此时UDP数据包首部中的目的端口部分,就是客户端发送这个数据的源端口。 66 | 67 |  68 | 69 | 客户端接收到响应的数据,发现目的端口是12656,就会恍然;原来是响应我上次从12656端口发送的数据。 70 | 71 | 服务器发送数据时,源端口不变。 72 | 73 | 5.防火墙可以设置开启/关闭一些端口来提高安全性。 74 | 75 | 常用命令行: 76 | 77 | netstat -an:查看被占用的端口 78 | 79 | netstat -anb:查看被占用的端口,占用端口的应用程序。 80 | 81 | telnet 主机 端口:查看是否可以访问主机的某个端口 82 | 83 | 安装telnet:控制面板-程序-启用或关闭Windows功能-勾选"Talnet Client" 84 | 85 |  86 | 87 | #### 3.注意服务器默认是用80端口监听http请求的 88 | 89 | 1.Tomcat服务器软件默认配置的监听的端口是8080,所以我们访问部署在Tomcat服务器上的应用时,一般要加上:8080来访问。 90 | 91 | 2.我们访问百度时:www.baidu.com 我们输入了域名,域名在解析成ip地址时,自动找到了百度服务器。但是我们没有指明端口呀,因为监听http请求的默认端口是80,即80可以不加。 92 | 93 | 3.如果我们`想要直接访问部署在tomcat下的项目,不加8080端口`,通过直接访问网址不加8080端口。可以通过niginx监听http请求,监听80端口,然后转发给8080端口。 94 | 95 | #### 4.抓包看一下UDP数据 96 | 97 | 1.传输层的首部是1f 40 0f a8 00 3f 0e 73这8个字节,下面的部分02开始是传输层的数据部分。 98 | 99 |  100 | 101 |  102 | 103 | 2.传输层的数据会传给网络层,被封装成包:而且数据部分是从1f 40 0f a8 00 3f 0e 73这8个字节开始。 104 | 105 |  106 | 107 | ### 2.传输层协议:TCP协议 108 | 109 |  110 | 111 | 1.TCP协议的几个要点 112 | 113 | 1.可靠传输 114 | 115 | 先大致了解一下: 116 | 117 | 如果服务器响应给客户端的数据太大,那么会切成不同的包一次发过去。客户端每接收一个包都会给服务 器一个回应:我收到这个了这个包。服务器就会知道这个给包成功发送了。 118 | 119 | 如果有一个包在发送过路程中被路由器丢掉了,那么客户端收不到这个包,服务器也就收不到客户端给 服务器关于接收到这个包的响应。那么服务器在之后就会重新再发送一遍这个包。 120 | 121 | 2.流量控制 122 | 123 | 3.拥塞控制。 124 | 125 | 4.连接管理 126 | 127 | 1.建立连接 128 | 129 | 2.释放连接 130 | 131 | #### 1.TCP协议报文段首部 132 | 133 | 1.TCP协议报文段首部包含两个部分: 134 | 135 | 1.20个字节的固定首部部分 136 | 137 | 2.选项和填充部分长度不固定 138 | 139 | 所以TCP协议报文段的首部最少20个字节。 140 | 141 | #### 2.首部各组成部分 142 | 143 | ##### 1.数据偏移 144 | 145 | 占4位,取值范围是0x0101~0x1111。 146 | 147 | 乘以4:就是TCP报文段的首部长度,最小20~最大60字节。 148 | 149 | 因为TCP报文段首部最小是20字节,所以数据偏移的最小值是20/4=5,0x0101。 150 | 151 | 这部分和网络层首部一样。 152 | 153 | * 首部长度:就是右边数据向右的偏移量。 154 | 155 | ##### 2.保留 156 | 157 | 占3位,目前用不到。预防以后可能用到,现在全是0。 158 | 159 | ##### 3.标志位: 160 | 161 |  162 | 163 | 1.占9位,前三位是保留位 164 | 165 |  166 | 167 | 1.URG=Urgent 168 | 169 | 当URG=1时,紧急指针字段才有效。表明当前报文字段中有紧急数据,优先传输。 170 | 171 |  172 | 173 | 2.ACK=Ackownledgment 174 | 175 | 当ACK=1时,确认号ack字段才有效。 176 | 177 | 3.PSH=Push 178 | 179 | 一般不关注,用在交互式网络通信中。 180 | 181 | 4.RST=Reset 182 | 183 | 当RST=1时,表明连接中出现严重差错,必须释放连接,然后再重新建立连接。 184 | 185 | 5.SYN=Synchronization 186 | 187 | 1.当SYN=1,ACK=0时,表明这是一个建立连接的请求。 188 | 189 |  190 | 191 | 2.若对方同意建立连接,则回复SYN=1,ACK=1。 192 | 193 |  194 | 195 | 6.FIN=Finish 196 | 197 | 当FIN=1时,表明数据已经发送完毕,要求释放连接。 198 | 199 | ##### 4.注意:另一种说法 200 | 201 | 1.保留为6位,标志位6位。 202 | 203 | 但是其实两种说法差不多,因为标志位的前3位也是基本上不用的,所以会被算作保留位。 204 | 205 | 所以有些资料干脆说保留位6位,标志位6位。 206 | 207 | ##### 5.TCP:一个细节 208 | 209 | 1.UDP首部中有个16位的字段记录了整个UDP报文段的长度(首部+数据); 210 | 211 | 但是TCP首部中仅仅有4位的字段记录了TCP报文段的首部长度,并没有字段记录TCP报文段的数据长度。 212 | 213 | 2.那怎么知道TCP报文段的数据长度呢? 214 | 215 | 1.其实UDP首部的这个记录UDP报文段的长度的字段是冗余的,不用这个字段也能就计算出UDP报文数据部分 的长度: 216 | 217 | UDP首部固定是8字节 218 | 219 | 所以UDP数据部分是:网络层的总长度-网络层的首部长度-UDP报文首部长度 220 | 221 | 2.UDP的这个16位的字段,纯粹是为了保证首部是32bit对齐: 222 | 223 | 思考数据偏移*4代表了TCP报文段首部的长度,那么TCP报文首部长度能不能等于11?可能不行啊, 224 | 225 | 必须是4的倍数。所以这个16位的记录UDP报文段的长度的字段之所以占16位,就是为了满足UDP报文段 226 | 227 | 首部固定部分长度是4的倍数:如果没有这16位,那么UDP报文段首部固定部分长度3个字节,就不是4的倍数 了。 228 | 229 | 3.所以TCP/UDP的数据长度,完全可以由IP数据包的首部推测出来。 230 | 231 | 传输层的首部长度是固定的或者可知的: 232 | 233 | 1.UDP首部:20字节 234 | 235 | 2.TCP首部:存放在首部的数据偏移字段 236 | 237 | 3.网络层的总长度和首部长度:都有对应字段存储。 238 | 239 |  240 | 241 | 传输层数据部分是=网络层的总长度-网络层的首部长度-传输层报文首部长度 242 | 243 | ##### 6.TCP校验和-Checksum 244 | 245 | 1.跟UDP一样,TCP校验和的计算内容:伪首部+首部+数据 246 | 247 | 2.伪首部:占用12字节,仅在计算校验和时起作用,并不会传递给网络层。 248 | 249 | ##### 7.序号(Sequence Number) 250 | 251 | 1.占4字节。 252 | 253 | 2.首先,在传输过程中的每一个字节都会有一个编号,而且连续的字节编号也连续。; 254 | 255 | 类似于每一个字节都有一个内存地址。 256 | 257 | 3.在建立连接后,序号代表:这一次传给对方的TCP数据部分的第一个字节的编号。 258 | 259 | 比如A要发给B400字节的数据,分成4段发。第一个TCP报文段的数据部分是1~100,那么这个报文段的序号部分就是1(假设第一个字节的编号就是1)。 260 | 261 | 那么第二个报文段的数据部分就是101~200,这个报文段的序号部分就是101。 262 | 263 | ##### 8.确认号(Ackownledgment Number) 264 | 265 | 1.占4字节。 266 | 267 | 2.在建立连接后,确认号代表:期望对方下一次传过来的TCP数据部分的第一个字节的编号。 268 | 269 | 3.确认号ack,在标志位ACK为1时才有效。 270 | 271 | ##### 9.窗口(Window) 272 | 273 | 1.占2字节; 274 | 275 | 2.这个字段有流量控制功能,用于告诉对方下一次允许发送的数据大小(单位字节)。 276 | 277 | #### 3.TCP可靠传输 278 | 279 | ##### 1.实现TCP可靠传输 -- 停止等待ARQ协议 280 | 281 | ARQ(Automatic Repeat-reQuest):自动重传请求。 282 | 283 | 1.假设A要发送给B发送3个包,如果发送第一个包M1时,B没有接收到。那么B就不会给A发送:确认收到M1包这个消息。然后A端等待接收这个消息,直到超时。然后就会重新发送M1包。 284 | 285 |  286 | 287 | 288 | 289 | 2.停止等待ARQ协议实现TCP可靠传输的两种情况: 290 | 291 | 1.确认(信息)丢失: 292 | 293 | B收到A发送的M1包,然后返回一个确认信息。但是这个确认收到M1信息在传输时,丢失了。那么A在 等待超时后会在次发送一个M1包,此时B端接收后,就会收到两个M1包,B端会丢掉一个M1包,再返回确 认收到M1包的信息给A端。 294 | 295 | 2.确认(信息)迟到 296 | 297 | B收到A发送的M1包,然后返回一个确认信息。但是这个确认收到M1信息可能因为线路或者网络问题传 输的很慢,可能造成A端等待超时,再次发送M1包。B端接收到这第二个M1包后,发现已经收到过了,就 会丢掉一个M1包,再次发送确认收到M1信息。 298 | 299 | 对于A端来说,收到B端发送的确认收到M1信息后,就会接着发送M2信息。之后可能还会再次收到确认 收到M1信息。A端收到这个迟到的确认信息,发现之前收到过了,那么A端就会不响应这个信息。 300 | 301 | 3.停止等待ARQ协议能够保证TCP的可靠传输,但是因为必须等上一个数据传输结束,下一个信息才能传输,所以效率很低。 302 | 303 | ##### 2.改进:连续ARQ协议+滑动窗口协议+SACK选择性确认 304 | 305 |  306 | 307 | 1.连续ARQ:发送窗口中有4个分组,会一口气发送完然后再等待确认信息。而且确认信息,也只会发送确认 收到最后一个分组的确认信息。等价于确认收到所有分组信息了。 308 | 309 | 2.滑动窗口:B这边有一个缓存窗口,用来暂时存放每次从A发送来的数据。这个窗口的大小会告诉A。窗口的 大小,代表每次最多能能接收多少分组。发送方的窗口大小,一般是由接收方决定的。 310 | 311 |  312 | 313 | 3.图示一个传输过程:注意序号Seq和确认号ack 314 | 315 |  316 | 317 | 4.SACK选择性确认:Selective Acknowledgment 318 | 319 | 1.在TCP通信过程中,如果发送序列中间某个数据包丢失(比如1,2,3,4,5中的3丢失了)。 320 | 321 | TCP会通过重传最后确认的分组(2)的后续分组(3,4,5):收到的确认信息中的确认分组是2,那么发 送端会重传3,4,5。这样原先已经正确传输的分组也可能重复发送(比如4,5),降低了TCP性能。 322 | 323 | 2.为改善上述情况,发展了SACK(Selective Acknowledgment)技术: 324 | 325 | 告诉发送方哪些数据丢失,哪些数据已经提前收到。可以使TCP只重新发送丢失的包(比如3),不用发送 后续所有的分组(比如4,5)。 326 | 327 | 3.SACK信息会放在TCP首部的选项部分:此时TCP首部的选项部分就是SACK选项。 328 | 329 |  330 | 331 | 5.抓包演示: 332 | 333 |  334 | 335 | 1.前面5个:发了5个分组。 336 | 337 | 前面5个包大小分别是312,1280,1280,1280,1280 338 | 339 | 2.后面1个:我给服务器回复一个确认信息。 340 | 341 | 我确认收到了5432字节,请给我发送5433及之后的字节,我的窗口大小是262400。 342 | 343 | 3.注意服务器发给我的第一个包的Seq是1,但是其实这个序号是相对序号。 344 | 345 | 相对于谁的序号呢?注意到下面还有个原始(raw)序号,那么原始序号 - 相对序号 = 基准数。 346 | 347 | 3277832203 - 1 = 3277832202 348 | 349 |  350 | 351 | 看第二个包:得到基准数也是3277832202 352 | 353 |  354 | 355 | 4.这个基准数其实是一个标识:标识这些连接属于同一个请求。这个值在连接的时候创建的。 356 | 357 | 5.序号部分放的是原始值Sequence Number(raw),而不是相对值。 358 | 359 | ##### 3.疑问: 360 | 361 | 1.如果一个包重传了N次还是失败,会一直持续重传到成功为止吗? 362 | 363 | 这个取决于操作系统的设置,比如有些操作系统,重传5次还未成功就会发送reset报文(RST)断开TCP。 364 | 365 | 即发送端超出一定的重传次数或等待时间,还没有收到来自接收端的确认报文,于是发送reset报文。 366 | 367 | 当RST=1时,表明连接出现严重错误,必须释放连接,然后再重新建立连接。 368 | 369 | 2.如果接收窗口最多能接收4个包,但是发送方只发送了2个包,接收方如何确定后面还有没有第3个包呢? 370 | 371 | 等待一定时间后还是没有第3个包发过来,接收端就认为只传过来了2个包(无论是传输过程中丢包还是只有2 个包)。接收端就会返回确认信息:确认收到2个包。 372 | 373 | ##### 4.思考 374 | 375 | 1.为什么选择在传输层就将数据“大卸八块”分成多个段,而不是等到网络层再分片传递给数据链路层? 376 | 377 | 因为可以提高重传的性能:需要明确的是,可靠传输是在传输层进行控制的,即没有收到确认信息后,发送 端会重新发送这个报文段。 378 | 379 | 所以如果在传输层不分段,一旦出现数据丢失,整个传输层的数据都得重传。 380 | 381 | 如果在传输层分了段,一旦出现数据丢失,只需要重传丢失的那些段即可。 382 | 383 | #### 4.TCP的流量控制 384 | 385 | 1.如果接收方的缓存区满了,发送方还是疯狂的发送数据,接收方只能把收到的数据包丢掉,大量的丢包会极大着浪费网络资源。所以要进行流量控制。 386 | 387 | 2.什么是流量控制:让发送方的发送速率不要太快,让接收方来得及接收处理。 388 | 389 | 3.缓存区和窗口是不同的概念:缓存区要比窗口大很多,每次收到一窗口大小的数据,会先放到缓存区中。 390 | 391 | 4.原理: 392 | 393 | 通过确认报文中窗口字段来控制发送方的发送速率。 394 | 395 | 发送方的发送窗口大小不能超过接收方给出的窗口大小 396 | 397 | 当发送方收到接收窗口的大小为0时,发送方就会停止发送数据。 398 | 399 |  400 | 401 | 5.流量控制:特殊情况 402 | 403 | 1.有一种特殊情况:一开始接收方给发送方发送了报文段中的窗口字段值为0。后面,接收方又有了一些存储 空间,会给发送方发送一个非0窗口的报文但是这个报文丢了。 404 | 405 | 2.结果就是:发送方一直认为接收方的窗口为0,不发送报文;接收方一直等不到数据,一直等待;双方陷入 僵局。 406 | 407 | 3.解决方案:发送方主动询问窗口大小。 408 | 409 | 当发送方收到窗口为0的报文时,发送方会停止发送报文,但是同时会开启一个定时器,隔一段时间就发个测 试报文去询问接收方最新的窗口大小。如果接收方的窗口大小还是0,则发送方会再次刷新启动这个定时器。 410 | 411 | #### 5.TCP:拥塞控制 412 | 413 |  414 | 415 | ##### 1.什么是拥塞 416 | 417 | 1.如果一个路由器R3允许通过的最大带宽是1000M,此时R3路由器左侧又连接这个两个路由器R1和R2,R1的最大带宽是700M,R2的最大带宽是600M。那么此时就极有可能发生拥塞现象。 418 | 419 | 在理想情况下,R3能同时允许1000M的数据通过,但是R1和R2最多能通过1300M。此时就可能发生R3路由器来不及处理这么多数据,或者无法一次性通过这么多数据,就会造成拥塞现象。R3就会丢弃掉过载的数据包。 420 | 421 | 拥塞是指到达通信子网中某一部分的分组数量过多,使得该部分网络来不及处理,一致引起这个部分乃至整个网络性能下降的现象,严重时甚至会导致网络通信业务陷入停顿,即出现死锁现象。 422 | 423 | 2.理想情况和实际情况是不同的 424 | 425 |  426 | 427 | 428 | 429 | 如果某个链路的理想情况下的吞吐量是1000M,但是实际情况由于数据可能在传输过程中可能会互相干扰。往往实际负载在不到1000M时,该链路的吞吐量就达到最大了。 430 | 431 | 之后再加大负载就会造成拥塞。 432 | 433 | ##### 2.拥塞控制 434 | 435 | 1.防止过多的数据注入到网络中,避免网络中的路由器或链路过载。 436 | 437 | 2.拥塞控制是一个全局性的过程(流量控制,是两端,点对点的控制过程)。 438 | 439 | 要整个链路来协同控制,涉及到所有的主机,路由器,以及与降低网络传输性能有关的所有因素,是大家共 同努力的结果。 440 | 441 | 442 | 443 | ##### 3.几个缩写: 444 | 445 | * 1. MSS(Maxium Segment Size):每个段的数据部分的最大长度 446 | 447 | 两端建立连接时,会商定一个合适的MSS值,即MSS在建立连接时确定。 448 | 449 | 每个段数据部分最大值的理论值:1460字节 450 | 451 |  452 | 453 | * 抓包观察这个字段: 454 | 455 | 首先这个MSS段的数据部分的最大长度是在建立连接时确定的,那肯定是在三次握手时确定的: 456 | 457 | 当SYN=1,ACK=0时,表明这是一个建立连接的请求。 458 | 459 |  460 | 461 | 462 | 463 | * 查看这个TCP报文的首部:发现TCP首部长度是32字节,所以有12字节在选项Options部分中。 464 | 465 | 在Options部分中发现了MSS字段且是1460(注意这个值不是固定的,两端发送的的TCP报文中这个值可能是 不一样的)。 466 | 467 | * 这个选项部分Options就是存放两端确定的一些东西: 468 | 469 | 比如MSS段的数据部分的最大长度,是否允许SACK 选择性确认(SACK permitted) 470 | 471 | * 注意这个值不是固定的,两端发送的的TCP报文中这个值可能是不一样的。 472 | 473 | 比如A发给B的报文中MSS是1460,B发给A的报文中MSS是1412,那么此时MSS在两者中取最小值。为了兼 顾两者,这样传输数据两者都能接收。 474 | 475 | MSS在建立连接时确定(协商的)。 476 | 477 | * 2.cwnd(congestion window):拥塞窗口 478 | * 进行拥塞控制,会动态的变化。 479 | 480 | * 3.rwnd(receive window):接收窗口 481 | * 接收方告诉发送方,你最多一次能发送多少的TCP报文段。 482 | * 4.swnd(send window):发送窗口 483 | * swnd = min(cwnd, rwnd) 484 | * 实际发送方的发送窗口,取拥塞窗口和接收窗口的最小值。 485 | 486 | ##### 4.拥塞控制的方法: 487 | 488 | ###### 1.慢开始(slow start,慢启动) 489 | 490 | 加入一开始接收方告诉发送方的接收窗口rwnd=3000比较大,且MSS=100比较小。所以理论上发送方可以以口气发30个报文段给接收方。但是考虑到拥塞控制的话,拥塞窗口cwnd=100一开始会设置的比较小。那么发送窗口swnd会取拥塞窗口cwnd和接收窗口rwnd两者的最小值100,所以第一次会只发送1个报文段。 491 | 492 | 发送一个报文段后,发现网络状况良好。那么拥塞窗口会 * 2,cwnd=200。发送窗口取两者最小值为swnd=200,所以这次发送2个报文段。发现网络状况依然良好,拥塞窗口继续 * 2,cwnd=400。下一次发送4个报文段,如果网络状况依然良好的话,拥塞窗口cwnd * 2。 493 | 494 | 发送窗口缓慢增长,试探增长,慢慢开始。试探接收方的接收程度。 495 | 496 | * cwnd的初始值比较小,然后随着TCP报文段被接收方确认(收到一个ACK)而成倍增长(指数级)。 497 | 498 |  499 | 500 | ###### 2.拥塞避免(congestion avoidacne) 501 | 502 | 1.在慢开始的基础上,为拥塞窗口cwnd加上一个慢开始阈值slow start threshold,cwnd在到达阈值之前只要网络良好没有出现拥塞等状况,就会成指数增长(乘以2);如果达到阈值而且网络状况依然良好,拥塞窗口cwnd会呈乘法级增长(每次加固定值)。 503 | 504 | 2.当出现拥塞时(发现开始丢包/报文段),就会把慢开始阈值slow start threshold减半,同时从头开始执行慢开始算法(cwnd从初始值开始)。 505 | 506 |  507 | 508 | 3.ssthresh(slow start threshold):慢开始阈值,cwnd达到阈值后,以线性方式增长。 509 | 510 | 4.拥塞避免(加法增大):拥塞窗口缓慢增大,以防止网络过早出现拥塞。 511 | 512 | 5.乘法减小:只要网络出现拥塞(发现开始丢包了),把ssthresh减半,与此同时,开始重新执行慢开始算法。 513 | 514 | 6.当网络出现频繁拥塞的话,ssthresh这个值会下降的很快。 515 | 516 | ###### 3.快速重传(fast restransmit) 517 | 518 | 1.之前的实现TCP可靠传输时,有一个重传机制是“超时重传”。在ARQ自动重传请求机制中,如果A等待接受B的确认消息,如果等待超时的话,就会重新发送上一个报文段。 519 | 520 |  521 | 522 | 2.快重传机制:在接收方和发送方都进行了限制 523 | 524 | 3.接收方: 525 | 526 | 之前的做法:A发送5个段给B时,B只有等A的5个都发送完时或最后一个段超时时,才给A发确认信息:我 收到了哪些段。 527 | 528 |  529 | 530 | 快重传做法:当接收方收到第二个分组后,返回一个确认收到分组2。但是没有收到第三个分组,直接收 到了分组4,即收到了一个失序的分组。那么在收到分组4后,会立即发出重复的确认(上一个确认信 息):确认收到了分组2。然后继续收到分组5,再次发送确认收到了分组2;然后继续收到分组6,再次发 送确认收到了分组2。 531 | 532 |  533 | 534 | 4.发送方: 535 | 536 | 如果连续收到3个重复的确认(总共4个相同的确认),就会立即重传尚未收到的报文段。 537 | 538 | 而不必继续等待重传计时器到期后再重传。 539 | 540 | ###### 4.快速恢复(fast recovery) 541 | 542 | ######  543 | 544 | 1.拥塞控制是上述4个方法综合来治理的。 545 | 546 | 2.大致过程: 547 | 548 | 慢开始算法开始增大拥塞窗口,当拥塞窗口以指数增长,直到达到慢开始阈值后,执行拥塞避免算法即 拥塞窗口以线性增长。当收到3个重复的确认后,意识到此时开始掉包,产生拥塞了---->慢开始阈值乘法减 半,变成以前的一半: 549 | 550 | 之后又重新开始“慢开始算法”,拥塞窗口重初始值开始呈指数增长(这是旧版本的做法,已经弃置不 用)。但是这样效率较低,拥塞窗口应该在一个合适的初始值开始增大。 551 | 552 | 拥塞窗口直接以新的慢开始阈值作为初始值,开始以线性增长。 553 | 554 | 3.当发送方连续收到3个重复确认后,就意识到此时发生了丢包的现象,可能出现了拥塞。就执行“乘法减 小”,把慢开始阈值减半。之后不会执行慢开始算法,而是将拥塞窗口的值直接设置为慢开始阈值减半后的 新阈值,并且呈线性增长。 555 | 556 | ###### 5.发送窗口的限制条件 557 | 558 | 1.发送窗口的最大值:swnd = min(cwnd, rwnd) 559 | 560 | 2.当rwnd < cwnd时,是接收方的接收能力限制发送窗口的最大值。 561 | 562 | 3.cwnd < rwnd时,则是网络的拥塞限制发送窗口的最大值。 563 | 564 | ###### 6.拥塞控制可以理解为是在可靠传输,流量控制的基础上,进一步来控制网络的状态,协调网络的情况。尽量避免网络拥塞,出现状况。 565 | 566 | 567 | 568 | -------------------------------------------------------------------------------- /6.TCP--连接管理.md: -------------------------------------------------------------------------------- 1 | #### 6.TCP--连接管理 2 | 3 | 1.建立连接 4 | 5 | 2.释放连接 6 | 7 | ##### 1.TCP:序号,确认号详细步骤 8 | 9 | 在发送一个http请求前,要先建立一个稳定的连接。 10 | 11 |  12 | 13 | ###### 1.先回顾一下: 14 | 15 | 序号Seq:我当前发的包的数据部分的第一个字节的编号(在分段之前的整个数据包的编号)。 16 | 17 | 可以理解为我当前这个包的数据从哪个字节发。 18 | 19 | 确认号Ack:在建立连接后,确认号代表:期望对方下一次穿过来的TCP数据部分的第一个字节的编号。 20 | 21 | 也可以理解,我确认收到了这个编号前面字节的数据。确认号Ack只有在标志位ACK为1时明才有效。 22 | 23 | ###### 2.序号,确认号:相对 24 | 25 |  26 | 27 |  28 | 29 | 2.1存放在TCP首部的序号和确认号其实都是原始值 30 | 31 | 2.2在建立连接时,客户端会告诉服务器一个序号初始值;服务器也会告诉客户端一个序号初始值;这两个 初始值可以不同,而且分别在客户端和服务器中起作用。 32 | 33 | 比如:服务器给客户端发送数据时,序号字段的值就是在序号初始值上在加上发送的数据部分的首字节 编号。客户端给服务器发送数据时,序号字段的值就是在序号初始值上在加上发送的数据部分的首字节编 号。 34 | 35 | 2.3双方都是在建立连接的时候确定好,以后各自的序号从哪里开始。 36 | 37 | ###### 3.分析一下Seq和Ack的变化过程 38 | 39 | 1.客户端给服务器发起建立连接的请求: 40 | 41 | 标志位SYN=1,确认客户端序号初始值seq = 123456。 42 | 43 | 2.服务器响应客户端建立连接的请求: 44 | 45 | 标志位SYN=1,ACK=1,确认服务器序号初始值seq=234567 46 | 47 | 3.客户端响应客户端:我知道你同意建立连接了 48 | 49 | 标志位SYN=0, ACK=1:连接建立好了,下面可以发送http请求了。 50 | 51 | 4.客户端给服务器发送第一个报文段: 52 | 53 | 序号seq = 123456 + 1,len = 100 54 | 55 | 5.服务器收到这个报文段响应:下一个包希望从这个位置开始接收,前面的都接收到了。 56 | 57 | 确认号ack = 123456 + 1 + 100 58 | 59 | 6.服务器也会给客户端发送第一个数据: 60 | 61 | 序号seq = 234567 + 1,len = 100 62 | 63 | 7.客户端接收到这个数据后,给服务器一个响应: 64 | 65 | 确认号ack = 234567 + 1 + 100 66 | 67 |  68 | 69 | ###### 4.序号确认号:演示详细变化过程 70 | 71 | ######  72 | 73 | 1,2,3:是建立连接。 74 | 75 | 4:客户端发送HTTP请求给服务器。 76 | 77 | 5,6,7,8:服务器连发4个数据给客户端。 78 | 79 | 9:客户端响应服务器。 80 | 81 | 1.第1步:客户端向服务器发起建立连接的请求: 82 | 83 | 客户端序号初始值是seq=s1,确认号ack=0因为没有收到数据。 84 | 85 |  86 | 87 | 2.第2步:服务器响应客户端发起的建立连接请求: 88 | 89 | 服务器序号初始值seq=s2,确认号ack=s1+1。虽然客户端发给服务器的请求`没有数据部分,只有TCP首部。`但是服务器端仍然收到客户端发给服务器的数据,所以要有响应给客户端一个确认号,数据部分收到了0个字节,此时的ack=s1+0+1。意味着,我期待你下次发给我的数据部分从第一个字节开始。 90 | 91 |  92 | 93 | 3.第3步:客户端响应服务器的响应 94 | 95 | 按理说这次也是没有数据部分的,但是为了响应上一次服务器的响应TCP报文的确认号ack=s1+1,所以这次TCP报文的序号是seq=s1+1。 96 | 97 | 同时客户端发现这次我收到的服务器响应的TCP报文的数据部分是0个字节,所以下次希望从1字节收。响应服务器期待下次发给我的数据部分从第一个字节开始ack=s2+0+1。 98 | 99 |  100 | 101 | 4.第4步:真正发送一个HTTP请求。 102 | 103 | 此时的TCP肯定是有数据的,因为发送了HTTP请求,TCP会封装这个HTTP请求到自己的数据部分。 104 | 105 |  106 | 107 | 客户端给服务器发送一个HTTP请求,上一次客户端接收到服务器的TCP报文是在第2步。客户端当时接收到的报文中数据部分是len=0。所以在第4步,客户端继续发请求给服务器时的确认号ack=s2+0+1。 108 | 109 | 且上一次服务器响应的ack=s1+1,所以这次的序号seq=s1+1,且长度len=k。 110 | 111 | 所以第4步和第3步的seq和ack都是一样的,因为都是对第2步的回应。只是第四步有真正的数据部分。 112 | 113 | 5.第5,6,7,8步:服务器给客户端发送数据 114 | 115 | 服务器要响应给客户端的数据分4次发送。这4次发送的TCP报文段中的确认号ack都是s1+k+1。因为ack表示响应接收到上一次对方发给自己的数据长度,并且期望下一次从哪个字节开始接收。 116 | 117 | 序号分别是s2+1,s2+b1+1,s2+b1+b2+1,s2+b1+b2+b3+1。 118 | 119 | 6.第9步:客户端连续收到了服务器发送的4个TCP数据段 120 | 121 | 客户端响应给服务器一个TCP报文段: 122 | 123 | seq=s1+k+1,就是上一次就收到服务器发送的报文的ack。 124 | 125 | ack=s2+b1+b2+b3+b4+1,但是此时只是个确认TCP,所以数据部分len=0。 126 | 127 | 7.完整图示 128 | 129 |  130 | 131 | 132 | 133 | ##### 2.TCP建立连接:3次握手 134 | 135 | ###### 1. 3次握手概述 136 | 137 | 为了建立稳定的TCP连接,通信双方必须从对方了解如下信息: 138 | 139 | 1.对方报文发送的开始序号Seq。 140 | 141 | 2.对方发送数据的缓冲区大小。 142 | 143 | 3.能被接收的报文段的数据部分的最大长度MSS。 144 | 145 | 4.被支持的TCP选项:MSS,,是否支持SACK,窗口缩放系数Window scale来确认对方能接受的窗口大小。 146 | 147 | 在TCP协议中,通信双方将通过三次TCP报文实现对以上信息的了解,并在此基础上建立一个TCP链接。而通信双方的三次TCP报文段的交换过程,也就是通常所说的TCP实现建立连接的三次握手过程。一般是客户端主动发起建立连接的请求。 148 | 149 |  150 | 151 | ###### 2.过程分析一下 152 | 153 | 1.首先客户端处于关闭状态CLOSED,服务器是开启的处于监听状态LISTEN,比如监听某一端口。 154 | 155 | 2.客户端想和服务器建立连接:客户端回结束CLOSED状态,并发送一个建立连接的请求。发送的TCP报文中没有数据部分,且标志位SYN=1,ACK=0;还要告诉了服务器我的初始序号seq=x。之后客户端进入SYN-SENT同步已发送状态,表示客户端已发送SYN报文,等待服务器的第2次握手。-----第一次握手 156 | 157 | 3.服务器监听到客户端发送的这个建立连接的请求,如果没有问题的话,服务器就会给客户端一个响应,发送一个TCP报文段给客户端,报文的标志位SYN=1,ACK=1;并且返回给客户端一个初始化序号Seq=y和确认号ack=x+1来作为对收到的报文中的seq=x的回应。同时结束LISTEN状态,进入同步已接收SYN-RCVD状态,表示服务器接收到了SYN报文,服务器同意建立连接,并且我也想建立连接。-----第二次握手 158 | 159 | 4.客户端收到了服务器发过来的确认信息,如果没有问题的话,客户端会给服务器一个响应。发送一个TCP报文给服务器,报文的标志位ACK=1,注意此时的SYN=0标志位没有值;并且由于上一个报文中的ack=x+1,seq=y,所以响应的序号seq=x+1,确认号ack=y+1。同时结束同步已发送SYN-SENT状态,进入ESTABLiSHED连接已建立状态。----第三次握手 160 | 161 | 5.服务器接收到第三次握手后,会结束同步已接收SYN-RCVD状态,进入ESTABLiSHED连接已建立状态。连接就正式建立了。 162 | 163 | ###### 3.前两次握手的特点 164 | 165 | 标志位的SYN=1 166 | 167 | 数据部分的长度都是0,其实第三次握手的数据部分长度也是0. 168 | 169 | TCP头部的长度一般是32字节 170 | 171 | 1.固定20字节 172 | 173 | 2.选项部分12字节: 174 | 175 | 1.比如MSS即段的数据部分的最大长度, 176 | 177 | 2.是否允许SACK 选择性确认(SACK permitted), 178 | 179 | 3.window scale(窗口缩放系数):TCP首部有一个窗口字段,告诉对方对方下一次允许发送的数据大小。 但是窗口这个字段只有2个字节,所以存不了太大的数,所以还要乘上一个系数。这个数据 乘以 window scale窗口缩放系数才是真正的允许发送的数据大小。 180 | 181 |  182 | 183 | 184 | 185 | ###### 4.为什么建立连接的时候,要进行3次握手,2次不行吗? 186 | 187 | 主要原因:防止服务器端一直等待,浪费资源。 188 | 189 | 如果建立连接的时候,只进行了2次握手,可能会出现一种服务器端一直等待的情况: 190 | 191 | 1.客户端发送的第一个连接请求,因为网络延迟等原因,迟迟没有到达服务器端。 192 | 193 | 2.所以客户端迟迟没有收到服务器端的响应,就会再次发送一个连接请求。并且忘掉上一次的连接请求。 194 | 195 | 3.这次的连接请求很顺畅,两端成功建立了连接。并且数据传输完成后,连接又释放了。 196 | 197 | 4.1此时,第一个发送的连接请求姗姗来迟。注意!!!这个连接请求,客户端已经忘记了,或者说已经认为它失效了。但是服务器端确认为它是一个新的连接请求,那么服务器端会同意,并返回一个同意连接的响应。客户端收到这个响应有些不明所以,它会认为我没有给你发连接请求呀,所以会不管这个响应。结果就是客户端认为没有建立连接,但是服务器端认为已经建立连接了,所有服务器端会一直等待客户端发送数据过来,直到超时。 198 | 199 | 采用3次握手既可以避免上述现象: 200 | 201 | 4.2.如果是三次握手,在上述情况下:客户端没有向【服务器端的响应】发出确认,服务器端由于收不到确认,就知道客户端并没有建立连接。 202 | 203 | ###### 5.如果第三次握手失败了,会怎么处理? 204 | 205 | - 此时服务器端的状态为SYN-RCVD同步已接收状态,如若等不到客户端的ACK=1的TCP报文,客户端会重新发送SYN=1,ACK=1的TCP报文。 206 | 207 | - 如果服务器端多次重发SYN=1,ACK=1的TCP报文还是等不到客户端的ACK=1的TCP报文,服务器端就会发送RET=1的TCP报文,强制关闭连接。 208 | 209 |  210 | 211 | ##### 3.TCP:释放连接 212 | 213 | ###### 1.概述: 214 | 215 | 由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就会发送FIN标志位,表明我的数据已经发完了,我要终止终止这个方法向的连接。但是也仅仅表示这个方向上没有数据流动了,另一端仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。 216 | 217 | 全双工:意味着客户端可以给服务器发东西,服务器也可以给客户端发东西,并且可以同时进行。我发东西给你的同时,你也可以同时发数据给我。 218 | 219 | ###### 2.过程分析一下 220 | 221 |  222 | 223 | 1.首先客户端,服务器开始都处于ESTABLISHED链接已建立状态。 224 | 225 | 2.客户端先发起一个释放连接的请求,客户端会结束ESTABLISHED链接已建立状态,进入FIN-WAIT-1终止等待1状态。并且发送一个TCP报文,其中标志位FIN=1,ACK=1。表明我得数据已经发完了,我这边要断开连接了。(注意:ACK标记为1,说明ack确认号是有用的。) 226 | 227 | 3.服务器端会收到一个FIN=1的TCP报文,即客户端发送的连接释放的请求。然后回先回应一个ACK=1的报文给对方,并且结束ESTABLISHED状态,进入CLOSED-WAIT关闭等待状态。客户端不会回应这个响应,但是会结束IN-WAIT-1终止等待1状态,进入FIN-WAIT-2终止等待2状态. 228 | 229 | 4.处于CLOSED-WAIT关闭等待状态的服务器,还要考虑自己是否还有数据要发送给对方,如果没有,那么也向对方发送一个释放连接的请求报文FIN=1。并且结束CLOSED-WAIT关闭等待状态,进入LAST-ACK最后确认状态。 230 | 231 | 5.客户端收到FIN=1的报文后,就知道服务器端也没有东西要发了,服务器也要断开连接了。就会再响应一下这个请求。发送一个TCP报文给服务器ACK=1,并且结束FIN-WAIT-2终止等待2状态,进入TIME-WAIT时间等待状态。 232 | 233 | 6.服务器端收到最后这个响应后,就会结束LAST-ACK最后确认状态,进入CLOSED关闭状态。 234 | 235 | ###### 3.为什么要进行4次挥手 236 | 237 | 1.因为TCP是全双工通信,所以两头,两个传输方向要分别都关闭。 238 | 239 | 2.第一次挥手:当主机发出FIN报文段时 240 | 241 | 表示主机1告诉主机2,主机1已经没有数据要发送了,但是,此时主机1还是可以接受来自主机2的数据。 242 | 243 | 3.第2次挥手:当主机2返回ACK报文段时 244 | 245 | 表示主机2已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1. 246 | 247 | 4.第3次挥手,当主机2也发送了FIN报文段时 248 | 249 | 表示主机2告诉主机1,主机2已经没有数据要发送了。 250 | 251 | 5.第4次挥手:当主机1返回ACK报文段时 252 | 253 | 表示主机1已经知道主机2没有数据发送了,随后正式断开整个TCP连接。 254 | 255 | ###### 4.释放连接时的各个状态 256 | 257 | 1.FIN-WAIT-1:表示想要主动关闭连接 258 | 259 | 向对方发送了FIN报文,此时进入FIN-WAIT-1状态 260 | 261 | 2.CLOSE-WAIT:表示正在等待关闭。(在这个阶段,考虑自己需不需要关闭连接) 262 | 263 | 当对方发送FIN给自己,自己会回应一个ACK报文给对方,此时则进入CLOSE-WAIT状态。 264 | 265 | 在此状态下,需要考虑自己是否还有数据要发给对方,如果没有,发送FIN报文给对方,表明自己也要断开连接了。 266 | 267 | 3.FIN-WAIT-2:只要对方发送ACK确认后,主动方就会处于FIN-WAIT-2状态,等待看看对方是不是也要发送FIN报文,对方是不是也要结束连接结束。 268 | 269 | 4.CLOSING:一种比较罕见的例外状态。 270 | 271 | 表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。 272 | 273 | 如果双方几乎在同时准备关闭连接的话,那么就会出现双方同时发送FIN报文的情况,也即会出现CLOSING状态,表示双方都正在关闭连接。 274 | 275 | 5.LAST-ACK:被动关闭一方在发送FIN报文后,最后等待对方的ACK报文 276 | 277 | 当收到ACK报文后,即可进入CLOSED关闭连接状态了。 278 | 279 | 6.TIME-WAIT:表示主动方也收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可进入COLSED状态了。 280 | 281 | ###### 5.TCP连接:细节 282 | 283 | 1.TCP/IP协议栈在设计上,允许任何一方先发起断开请求。这里演示的是client主动断开请求。 284 | 285 | 2.client发送ACK后,需要有个TIME-WAIT阶段,等待一段时候后,再真正关闭连接。 286 | 287 | 一般是等待2倍的MSL(Maximum Segment Lifetime,最大分段生存期),即4分钟。 288 | 289 | MSL是TCP报文在Internet上的最大生存时间。 290 | 291 | 每个具体的TCP实现(操作系统实现TCP)都必须选择一个确定的MSL值,RFC 1122建议是2分钟。 292 | 293 | 3.为什么要有TIME-WAIT这个阶段。 294 | 295 | 主要是预防这种情况:如果没有TIME-WAIT阶段,client发送ACK=1报文后立马断开连接。但是因为网络原因,服务器端没有收到客户端的ACK报文。服务器端就会重发FIN=1报文。但是此时客户端已经关闭了。此时可能出现的情况: 296 | 297 | 1.client没有任何反应,服务器那边会干等,甚至多次重发FIN,浪费资源 298 | 299 | 2.cient启动了一个新的应用程序,并且刚好分配了同一个端口号,新的应用程序就会收到服务器端重发的FIN=1报文。那么客户端就会马上开始执行断开连接的操作。 300 | 301 | 但是客户端本来想和服务器建立连接的。 302 | 303 | 换句话说:有了TIME-WAIT阶段可以防止本次连接中产生的数据包误传入下一次连接中(因为本次连接中的数据包包括服务器端重发的FIN=1报文,都会在2MSL时间内消失:所以2MSL时间后没有收到再FIN=1报文,就可以确认服务器端接收到了客户端的ACK报文) 304 | 305 | 4.所以TIME-WAIT主要是预防对方端没有收到上一次发送的ACK=1报文,看看能不能收到对方端重发的FIN=1报文。如果在TIME-WAIT阶段又收到FIN=1报文,说明上一次发的ACK=1报文对方没有收到,那么就会再次发送一个ACK=1报文,帮助对方顺利关闭。 306 | 307 | ##### 4.保活,心跳包 308 | 309 | 日常开发中可能出现这种情况,服务器为了节约资源,可能会实现如果在1min中内,没有收到客户端发送的数据,那么就会主动发起一个4次挥手断开连接。之后客户端再想发送数据给客户端时,就要发起一个3次握手建立连接。这样可能导致频繁的建立连接过程。那么为了避免这个情况,客户端就要定期向服务器发送一个心跳包,保证连接存活。 310 | 311 | 传输层TCP有一个`keep-alive`机制(和应用层HTTP的keep-alive不同),可以设置这个保活时间和心跳包。但是一般不用,开发中我们可以自己设置,相对灵活。 312 | 313 | 314 | 315 | ##### 5.抓包实践 316 | 317 | ###### 1.只看到“3”次挥手。 318 | 319 | 有时候在使用抓包工具的时候,有可能只会看到“3”次挥手。其实是将第2,3次挥手合并。 320 | 321 | 因为当server接收到client的FIN是,发现自己也没有数据要发送给cilent了,这时server就会将给客户端的回应ACK=1报文段和自己的断开连接请求FIN=1,合并成一个同时发给客户端。 322 | 323 |  324 | 325 |  326 | 327 | 本来两件事时分开的,发两次报文段,但是发现自己也没有数据要发送给cilent了时,就会只发一个报文段,同时告诉客户端两件事: 328 | 329 | 1.已经知道client没有数据要发,知道client要断开链接了。响应client发送的FIN=1断开连接请求 330 | 331 | 2.server已经没有数据要发了,server也要断开连接。主动发送FIN=1断开连接请求。 332 | 333 | 334 | 335 | ###### 2.此时FIN-WAIT-2状态还有吗? 336 | 337 | 因为FIN-WAIT-2状态是等待:看看服务器是不是也要断开联机,等待服务器发送的FIN=1报文。但是在FIN-WAIT-1阶段就收到了一个报文且标志位ACK=1,FIN=1。那么就会直接进入TIME-WAIT状态,没有FIN-WAIT-2状态。 338 | 339 | 如果在FIN-WAIT-1状态下,收到了对方同时带FIN标志和ACK标志的报文时:可以直接进入TIME-WAIT状态,而无需经过FIN-WAIT-2状态。 340 | 341 | ##### 6.长连接和短连接 342 | 343 | 如果建立连接后,进行一轮交互后就不需要在交互数据了,会立马关闭。那就是短连接。偶尔交互。 344 | 345 | 如果建立连接后可以一直进行数据交互,直到超过某一等待时间后还没数据,才会断开,那就是长连接。交互很频繁 346 | 347 | 348 | 349 | ##### 7.Socket对象 350 | 351 | 1.客户端和服务器建立连接后,在软件层面的体现就是各自的内存中都有一个Socket对象。这两个对象建立了连接。而网卡只是收发数据,没有连接建立的概念。所以如果建立连接后,一直不断开。只会影响到内存,不会影响到网卡硬件。 352 | 353 | 连接只是一种就绪状态,双方准备好随时进行数据交互。 354 | 355 | 2.网卡的作用: 356 | 357 | 对接收到的数据包进行检验,看一下MAC地址是不是给我的,不是我的就会丢掉。 358 | 359 | 网卡有带宽的概念:传输速度。如果传过来的速度超过了网卡能接受的速度,数据就可能会被丢掉。 360 | 361 | 3.每个连接都会有一对Socket对象。 362 | 363 |  364 | 365 | 各个连接之间互不干扰。 -------------------------------------------------------------------------------- /7.应用层1.md: -------------------------------------------------------------------------------- 1 | #### 7.应用层(一) 2 | 3 |  4 | 5 |  6 | 7 | 我们开发人员,一般都是面向应用层的。 8 | 9 | ##### 1.应用层的常见协议 10 | 11 | 1.超文本传输协议:HTTP,HTTPS 12 | 13 | 2.文件传输:FTP 14 | 15 | 3.电子邮件:SMTP,POP3,IMAP 16 | 17 | 4.动态主机配置:DHCP 18 | 19 | 5.域名系统:DNS 20 | 21 | ##### 2.DNS协议: 22 | 23 | ###### 1.域名:Domain Name 24 | 25 | 由于IP地址不方便记忆,并且不能表达组织的名称和性质,人们设计除了域名(比如:baidu.com) 26 | 27 | 但实际上,为了能够访问到具体的主机,最终还是得知道目标主机的IP地址。 28 | 29 | 域名申请注册:https://wanwang.aliyun.com/ 30 | 31 | 2.为什么不干脆全程直接用域名,不用IP地址呢? 32 | 33 | 1.首先域名本身就比ip地址占用的数据量大。每个字母一个字节,一个域名可能就10几个字节。而在网络层IP协议包中的IP地址仅占4个字节。 34 | 35 | IP地址固定4个字节,域名随随便便都至少10几个字节,这无疑会增加路由器的负担,浪费流量。 36 | 37 | ###### 2.根据级别的不同,域名可以分类 38 | 39 | 1.根域名:最右边的点“.”,但一般省略。 40 | 41 | www.baidu.com. 42 | 43 |  44 | 45 | 2.顶级域名(Top-level Domain,简称TLD) 46 | 47 |  48 | 49 |  50 | 51 | 3.二级域名 52 | 53 |  54 | 55 | 4.三级域名 56 | 57 | ....... 58 | 59 | ###### 3.DNS概述 60 | 61 | DNS的全称是:Domain Name System,译为:域名系统。利用DNS协议,可以将域名解析成对应的IP地址。 62 | 63 | 1.在浏览器敲下www.baidu.com,想要访问百度服务器时,会先找DNS服务器 64 | 65 | 2.如果是第一次访问百度服务器,而且电脑中没有缓存百度的DNS信息时(DNS服务器也会缓存的)。此时就会发送一个DNS协议包给DNS服务器。DNS服务器就会经过一些列过程告诉你百度服务器的IP地址。 66 | 67 | 3.DNS服务器上存储有域名和IP地址的信息。 68 | 69 | 4.DNS是应用层的协议,所以底层也是走的传输层。DNS可以基于UDP协议,也可以基于TCP协议,服务器占用53端口。 70 | 71 | 5.DNS常用命令 72 | 73 | ipconfig/displaydns:查看DNS缓存记录 74 | 75 | ipconfig/flushdns:清空DNS缓存记录 76 | 77 | ping 域名 78 | 79 | nslookup域名 80 | 81 | ###### 4.找到example.microsoft.com的ip地址 82 | 83 |  84 | 85 | 1.客户端浏览器想要访问example.microsoft.com这个网站,假设是第一次访问,没有DNS服务相关的缓存。 86 | 87 | 2.那么客户端想要访问这个example.microsoft.com地址,就得先知道对应的IP地址,那么客户端会先发送一个请求,即DNS协议包给本地DNS服务器。本地DNS服务器收到DNS协议包后就会检查自己有没有这个域名对应的IP地址。 88 | 89 |  90 | 91 | 3.因为是第一次访问这个域名,那么本地DNS服务区和客户端本身都没有相关的缓存信息。由于所有的DNS服务器都记录了DNS根域名服务器的IP地址(每个DNS服务器都记录额DNS根域名服务器的IP地址和下一级DNS服务器的地址),那么本地DNS服务器会向根DNS服务器发送请求,询问根DNS服务器是否知道example.microsoft.com这个域名对应的IP地址。 92 | 93 | 4.显然根域名不会知道这个域名对应的IP,因为它只知道它下一级的DNS服务器的IP。但是他发现这个地址的顶级域名是com,所以会将下一级的comDNS服务器的IP地址返回给本地DNS服务器。 94 | 95 | 5.本地DNS服务器知道了comDNS服务器的ip地址后,就会发一个请求给comDNS服务器问它是否知道example.microsoft.com这个域名对应的IP地址。显然comDNS服务器也不知道这个域名对应的IP地址,但是它知道microsoft.com这级DNS服务器的IP地址,所以会将这个IP地址返回给本地DNS服务器。 96 | 97 | 6.本地DNS服务器继续发请求给microsoft.com这级DNS服务器,询问example.microsoft.com这个域名对应的IP地址。此时这个DNS服务器就知道他的下级example.microsoft.com这个服务器的IP地址了。并且把IP地址返回给本地DNS服务器。做好缓存后,再返回个客户端。 98 | 99 | ###### 5.DNS服务器小结 100 | 101 | 所有的DNS服务器都记录了DNS根域名服务器的IP地址。 102 | 103 | 上级DNS服务器记录了下一集DNS服务器的IP地址。 104 | 105 | 全球一共13台IPV4的DNS根域名服务器,25台IPV6的DNS根域名服务器。 106 | 107 | ##### 3.DHCP,动态主机配置协议 108 | 109 | Dynamic Host Configuration Protocol 110 | 111 | ###### 1.IP地址按照分配方式,可以分为:静态IP地址,动态IP地址。 112 | 113 | 动态IP地址是从动态主机配置协议(DHCP)服务器获得的地址。当每一次上网时,会随机分配一个IP地址,子网掩码,默认网关和DNS服务器。动态IP地址经常变化,每次设备连接到网络时,动态IP地址都会发生变化 114 | 115 | 1.从DHCP服务器自动获取IP地址。 116 | 117 | 2.适用场景:移动设备,无线设备。 118 | 119 | 静态IP地址是由网络管理员分配给设备的固定地址。 120 | 121 | 1.手动设置 122 | 123 | 2.适用场景:不怎么挪动的台式机(比如学校机房中的台式机),服务器等 124 | 125 | ###### 2.概述 126 | 127 | DHCP协议基于UDP协议,客户端是68端口,服务器是67端口 128 | 129 | 客户端会首先发一个DHCP请求给DHCP服务器,然后DHCP服务器会从IP地址池中,挑选一个IP地址“出租”给客户端一段时间,并且时间到期后就会回收。 130 | 131 | 平时家里上网的路由器就可以充当DHCP服务器。 132 | 133 | ###### 3.DHCP分配IP地址的4个阶段 134 | 135 | 1.DISCOVER:发现服务器 136 | 137 | 此时还没有IP地址,发广播包从附近找一个DHCP服务器。因为还没有IP地址,所以发的包的源IP是0.0.0.0,目标IP是255.255.255.255(说明谁都可以收到),目标MAC时FF:FF:FF:FF:FF:FF(说明谁都可以收到)。 138 | 139 | 2.OFFER:提供租约 140 | 141 | 当找到一个DHCP服务器时,这个DHCP服务器就会返回可以租用的IP地址,以及租用期限,子网掩码,网关,DNC等信息。 142 | 143 | 注意:此时可能有多个服务器提供租约。 144 | 145 | 3.REQUEST:选择IP地址 146 | 147 | 客户端选择一个OFFER,发送广播包进行回应。 148 | 149 | 4.ACKNOWLEDGE:确认 150 | 151 | 被选中的服务器发送ACK数据包给客户端。 152 | 153 | 到此DHCP分配IP地址已经完毕。 154 | 155 |  156 | 157 | ###### 4.DHCP细节 158 | 159 | 1.DHCP服务器可以跨网段分配IP地址吗? 160 | 161 | DHCP服务器,客户端不在同一个网段时,可以借助DHCP中继代理实现跨网段分配IP地址。 162 | 163 | 2.自动续约 164 | 165 | 客户端会在租期不足时,自动向DHCP服务器发送REQUEST信息申请续约。 166 | 167 | 3.常用命令 168 | 169 | ipconfig /all :可以看到DHCP相关的详细信息,比如租约过期时间,DHCP服务器地址等。 170 | 171 | ipconfig /release:释放租约(会断网) 172 | 173 | ipconfig /renew:重新申请IP地址/(没有到期的话)申请续约,延长租期。 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /8.HTTP(上).md: -------------------------------------------------------------------------------- 1 | #### HTTP(上) 2 | 3 | ##### 1.概述: 4 | 5 | HTTP(Hyper Test Transfer Protocol),译为超文本传输协议。 6 | 7 | 是互联网中应用最广泛的应用层协议之一。 8 | 9 | 设计HTTP最初的目的是,提供一种发布和接收HTML页面的方法(就是为了浏览网页的),由URI来标识具体的资源。 10 | 11 | URL是URI的一部分,URL能全网确定一个唯一的资源,URI不能唯一确定一个唯一资源(可以局部确定唯一的资源)。 12 | 13 |  14 | 15 | 后面用HTTP来传递的数据格式不仅仅是HTTP,用途非常广泛。 16 | 17 | ##### 2.版本迭代 18 | 19 | 1. 1991年,HTTP/0.9 20 | 21 | 只支持GET请求方法获取文本数据(比如HTML文档),且不支持请求头,响应头等,无法向服务器传递太多信息。 22 | 23 | 2. 1996年,HTTP/1.0 24 | 25 | 支持POST,HEAD等请求方式,支持请求头,响应头等,支持更多种数据类型(不再局限于文本数据)。 26 | 27 | 浏览器的每次请求都需要与服务器建立一个TCP连接,请求处理完成后立即断开TCP连接。即没法送一个HTTP请求我都要新建立一个连接,每次一个请求响应完,都要断掉这个连接。 28 | 29 | 即多个请求不能共用一个TCP连接,每个都要建立单独的TCP连接。 30 | 31 | 3. 1997年,HTTP/1.1(最经典,使用最广泛的版本) 32 | 33 | 支持PUT,DELETE等请求方法 34 | 35 | 采用持久连接(Connection:keep-alive),长连接; 36 | 37 | `多个请求可以共用一个TCP连接。` 38 | 39 | 4. 2015年,HTTP/2.0 40 | 5. 2018年,HTTP/3.0(还没成熟,草稿阶段) 41 | 42 | ##### 3.标准 43 | 44 | 1. HTTP的标准 45 | 46 | 由万维网写会(W3C),互联网工程任务组(IETF)协调制定,最终发布了一系列的RFC文档。 47 | 48 | RFC(Request For Comments,可以译为:请求意见稿)。 49 | 50 | HTTP/1.1.最早是在1997年的RFC 2068中记录的,该规范在1999年的RFC 2616中已经作废;2014年又由RFC 7230系列的RFC取代。 51 | 52 | HTTP/2标准于2015年5月以RFC 7540正式发表,取代HTTP/1.1成为HTTP的实现标准。 53 | 54 | 2. 中国的RFC 55 | 56 | 1996年3月,清华大学提交的适应不同国家和地区中文编码的汉字统一传输标准被IETF通过为RFC 1922 57 | 58 | ,称为中国大陆第一个被认可为RFC文件的提交协议。 59 | 60 | ##### 注意: 61 | 62 | RFC文档仅仅是一个标准,是个规范,要有服务器去实现它,也就是说到具体的实现时,可能和标准有些差异。比如其他人要开发一个HTTP服务器(比如Tomcat服务器),那么它要遵守这个RFC规范来解析报文。但是在实现这个HTTP服务器时,可以增加一些“容错能力”。比如有多少空格,都可以正确解析出来(不认为是错误的报文)。 63 | 64 | ##### 4.报文格式(简) 65 | 66 | ###### 1.先看一下浏览器Chrome解析的请求响应格式 67 | 68 | 注意:每一对key-value后还要跟一个换行符发送给服务器。冒号后跟一个空格。 69 | 70 |  71 | 72 |  73 | 74 | ###### 2.查看一下抓包工具抓到的HTTP报文格式 75 | 76 |  77 | 78 |  79 | 80 | 所以响应头response header和数据是一次性返回给客户端的。 81 | 82 | ###### 3.请求报文格式 83 | 84 | 请求行+请求头+请求体(GET请求是没有请求体的) 85 | 86 | POST请求是将请求参数放在请求体上,所以能放很多数据。 87 | 88 | GET请求是将请求参数拼接在请求行后面,所以放的数据有限。 89 | 90 |  91 | 92 |  93 | 94 | ###### 4.响应报文格式 95 | 96 |  97 | 98 | ##### 5.报文格式(详) 99 | 100 | ###### 1.ABNF(Augment BNF) 101 | 102 | 是BNF(Backus-Naur Form, 译为:巴克斯-瑙尔范式)的修改,增强版 103 | 104 | 在RFC 5234中表明:ABNF用作internet中通信协议的定义语言 105 | 106 | ABNF是最眼睛的HTTP报文格式描述形式,脱离ABNF谈论HTTP报文格式,往往都是不严谨的。 107 | 108 | 关于HTTP报文格式的定义: 109 | 110 | RFC 2616 4.HTTP Message(旧) 111 | 112 | RFC 7230 3.Message Format(新) 113 | 114 | ABNF核心规则: 115 | 116 |  117 | 118 | ###### 2.报文格式:整体 119 | 120 | 注意:request-line(请求行) / start-line(响应行)内部包含了一个CRLF 121 | 122 |  123 | 124 | ###### 3.报文格式 - request-line(请求行) / start-line(响应行) 125 | 126 |  127 | 128 |  129 | 130 | ###### 4.报文格式-heaer-field,message-body 131 | 132 |  133 | 134 | 注意: 135 | 136 | 请求头冒号后面可以是空格也可以是tab制表符。而且可以是多个或者0个。 137 | 138 | 消息体:多个字节或者0个字节。 139 | 140 | ###### 5.URL编码 141 | 142 | URL中一旦出现了一些特殊字符(比如中文,空格),需要进行编码。 143 | 144 | 在浏览器地址栏输入URL时,是采用UTF-8进行编码的 145 | 146 | 比如: 147 | 148 | 编码前:https://www.baidu.com/s?wd=百度 149 | 150 | 编码后:https://www.baidu.com/s?wd=%E7%99%BE%E5%BA%A6 151 | 152 | 可通过 Java 将 “百度” 用 UTF-8 解码后转为16进制查看: 153 | 154 | ```java 155 | import java.nio.charset.StandardCharsets; 156 | 157 | public class Main { 158 | public static void main(String[] args) throws Exception { 159 | byte[] bytes = "百度".getBytes(StandardCharsets.UTF_8); 160 | for (byte b : bytes) { 161 | System.out.print(Integer.toHexString(b & 0xFF) + " "); //保留低8位 162 | } 163 | } 164 | } 165 | 166 | //结果:e7 99 be e5 ba a6 167 | ``` 168 | 169 |  170 | 171 | ###### 6.Xshell + telnet面向报文与服务器交互 172 | 173 | 1.安装一个Xshell(安全终端模拟软件),在Xshell中使用telnet 174 | 175 | 1.可以直接面向HTTP报文与服务器交互 176 | 177 | 2.可以更清晰,更直观地看到请求报文,响应报文的内容 178 | 179 | 3.可以检验请求报文格式正确与否 180 | 181 | 2.telnet命令可以理解为与服务器`建立TCP连接`,然后我们可以`直接输入报文`来获取响应。 182 | 183 | 3.启动一个本地服务器,键入telnet localhost 8080。 184 | 185 | 成功建立连接,下面可以直接发送HTTP报文给服务器。 186 | 187 |  188 | 189 | 4.发送一个最简单的HTTP请求报文 190 | 191 | GET /hello/ HTTP/1.1 //注意URL最后还要加一个 “/” 192 | 193 | Host: localhost:8080 194 | 195 | 换行 196 | 197 | 回车确定:得到响应报文 198 | 199 | ##### 6.请求方法(9种) 200 | 201 | RFC 7231, section 4: Request methods: 描述了8中请求方法 202 | 203 | GET,HEAD,POST,PUT,DELETE,CONNECT,OPTIONS,TRACE 204 | 205 | RFC 5789, section 2: Patch method: 描述了PATCH方法 206 | 207 | ###### 1.几种方法简介 208 | 209 | 1.GET: 常用于读取的操作,请求参数直接拼接在URL的后面。(但是浏览器对URL是有长度限制的) 210 | 211 | 2.POST:常用于添加,修改,删除的操作,请求参数可以放到请求体中(没有大小限制),`而且也可以放参数在URL上面。` 212 | 213 | 3.HEAD:请求得到与GET请求相同的响应(只有响应行和响应头),但没有响应体。 214 | 215 | 使用场景:在下载一个大文件前,先获取其大小(HEAD),在根据响应头中的文件大小来决定是否要下载这个资源。如果要下载的话,那么在发送一个GET请求,以此可以节约宽带资源。 216 | 217 | 4.OPTIONS:用于获取目的资源所支持的通信选项,比如服务器支持的请求方法 218 | 219 | OPTIONS * HTTP/1.1 220 | 221 | 通过向Tomcat发送OPTIONS请求,可以知道它支持以下请求方法 222 | 223 |  224 | 225 | 5.PUT:用于对已存在的资源进行整体覆盖。(不安全,一般不用) 226 | 227 | 6.PATCH:用于对资源进行部分修改(资源不存在,会创建新的资源) 228 | 229 | 7.DELETE:用于删除指定的资源。(不安全,一般不用) 230 | 231 | 8.TRACE:请求服务器回显其收到的请求信息(发给服务的内容,服务器再返回发送的内容),主要用于HTTP请求的测试或诊断。 232 | 233 | 9.CONNECT:可以开启一个客户端与所请求资源之间的双向沟通的通道,它可以用来创建隧道(tunnel) 234 | 235 | 可以用来访问采用了SSL(HTTPS)协议的站点。 236 | 237 | ##### 7.请求头字段(**Request Header Fields**) 238 | 239 | 240 | 241 |  242 | 243 |  244 | 245 | 1.Referer请求头字段可以防盗链: 246 | 247 | 如果服务器中的某个资源,不想让外部用户随意访问,只能来自本公司的网站连接才能访问。那么就可以用这个Referer请求头字段来判断。如果该字段的URL不是本公司的网站链接,那么就拒绝这个访问请求。 248 | 249 | 2.q代表权重 250 | 251 | q 值越大,表示优先级越高,如果不指定q值,默认是1.0(1.0是最大值) 252 | 253 | 3.Range:可以用在多线程断点下载 254 | 255 | 充分利用CPU的多核:开4个线程,每个线程都发一个HTTP请求,根据Range请求头字段分别下载资源的某一部分。 256 | 257 | 断点:如果突然断网,客户端会记录线程1下载到哪里了,线程2下载的哪里了...;当网络恢复时,就可以从断点继续下载。 258 | 259 | 4.Connection: keep-alive 260 | 261 | 如果是keep-alive,就代表着是一个长连接。返回响应后,不要立马关闭。 262 | 263 | 5.Content-Type:告诉服务器我的请求体的类型,GET请求没有请求请求体,POST请求有请求体。 264 | 265 | 5.1.application/x-www-form-urlencoded: 266 | 267 | 默认的Content-Type类型是:application/x-www-form-urlencoded。表示用&分隔请求体中的参数,用=分隔键和值,字符用URL编码方式进行编码。 268 | 269 | ```html 270 |
272 | ``` 273 | 274 |  275 | 276 | 5.2.multipart/form-data: 277 | 278 | 可以在提交表单时,设置该请求头:multipart/form-data。文件上传时请求体必须使用这种的编码方式。 279 | 280 | ```html 281 | 283 | ``` 284 | 285 |  286 | 287 | ```java 288 | //只能取出来用&隔开的请求体中的参数,比如,application/x-www-form-urlencoded这种Content-Type编码的参数数据,或者GET请求中URL的参数。 289 | //multipart/form-data这种编码取不出来 290 | String name = req.getParameter("name"); 291 | String age = req.getParameter("age"); 292 | String photo = req.getParameter("photo"); 293 | 294 | //结果 295 | null 296 | null 297 | null 298 | ``` 299 | 300 | 301 | 302 | ##### 8.响应头字段(**Response Header Fields**) 303 | 304 |  305 | 306 |  307 | 308 |  309 | 310 | 1.Content-Type使用示例: 311 | 312 | 相当于告诉客户端:我返回给你的是一个HTML,且字符串使用ISO-8859-1编码的(所以客户端会用这个字符集解码:显然会乱码)。 313 | 314 |  315 | 316 | 相当于告诉客户端:我返回给你的是一个普通文本,那么里面的HTML语法不会被浏览器解析 317 | 318 | ```java 319 | response.setHeader("Content-Type", "text/plain; charset=ISO-8859-1"); 320 | ``` 321 | 322 |  323 | 324 | 2.Content-Disposition 使用实例: 325 | 326 | ```java 327 | @Override 328 | protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 329 | response.setContentType("text/plain; charset=UTF8"); 330 | response.setHeader("Content-Disposition", "attachment; filename=\"mj.txt\""); 331 | response.getWriter().write("这是我的文件数据"); 332 | } 333 | ``` 334 | 335 |  336 | 337 | ##### 9.状态码:Status Code 338 | 339 | ###### 1.在RFC 2616 10.Status Code Definitions规范中定义。 340 | 341 | 状态码指示HTTP请求会否已成功完成 342 | 343 | ###### 2.状态码可以分为5类 344 | 345 | 信息响应:100~199 346 | 347 | 成功响应:200~299 348 | 349 | 重定向:300~399 350 | 351 | 客户端错误:400~499 352 | 353 | 服务器错误:500~599 354 | 355 | ###### 3.常见状态码 356 | 357 | 1.100 Continue 358 | 359 | 情景: 360 | 361 | 客户端给服务器发送的HTTP请求报文中,包含URL,请求头,请求体。服务器接收到这个报文后,仅仅通过判断URL,请求头就发现这个请求不合法,拒绝。即没有判断请求体中的内容,就拒绝了这个HTTP请求,那么发送的报文中的请求体(请求体可能很大)就是多余的,效率低下的。 362 | 363 | 那么客户端为了提高效率,可以先发送的请求中只有URL,请求头。服务器收到后,如果拒绝了这个请求后,那么客户端这次没有发送请求体,即提高了效率。如果服务器通过判断URL和请求头愿意接收该请求,会发现这个请求缺少一个请求体,那么就会在响应报文中添加一个状态码100 Continue,让客户端将这次请求的请求体也发过来。 364 | 365 | 概述: 366 | 367 | 在某些情况下,如果服务器在不看请求体就拒绝请求时,客户端就发送请求体是不恰当的或低效的。 368 | 369 | 允许客户端发送带请求体的请求前,看看服务器是否愿意接收请求(服务器通过请求体判断)。 370 | 371 | 请求的初始部分已经被服务器收到,并且没有被服务器拒绝,服务器会响应给客户端状态码100 Continue。客户端应该继续发送剩余的请求,如果请求已经完成,就忽略这个响应。 372 | 373 | 374 | 375 | 2.200 OK:请求成功 376 | 377 | 378 | 379 | 3.302 Found:请求的资源被暂时的移动到了由Location头部指定的URL上 380 | 381 | 重定向: 382 | 383 | 1.首先发送一个登陆请求/login/,携带用户名和密码:即本来是请求URL是/login/ 384 | 385 | 2.用户名和密码正确:服务器返回一个302状态码,且还有个响应头Location: /home.html/ 386 | 387 | 3.客户端收到这个响应后,会再发送一个请求/home.html/:重定向,客户端再次发送一个请求。 388 | 389 | 4.代码: 390 | 391 | ```java 392 | response.sendRedirect("/hello/html/home.html"); 393 | //等价于: 394 | //response.setStatus(302); 395 | //response.setHeader("Location", "/hello/html/home.html"); 396 | ``` 397 | 398 | 5.图示: 399 | 400 | 401 | 402 | 4.304 Not Modified:说明无需再次传输请求的内容,也就是说可以使用缓存的内容。 403 | 404 | 客户端会缓存一些静态资源,比如HTML页面。 405 | 406 | 服务器发现客户端这次请求的内容我上一次已经给过你了,而且这次请求的内容在我的服务器这边根本就没有动过。`服务器端就会返回一个304状态码给客户端,和一些常规的响应头,不返回请求的资源了。`告诉客户端这次响应的内容,我就不响应给你了,你直接从自己的缓存中拿吧。 407 | 408 | 409 | 410 | 5.400 Bad Request:由于语法无效,服务器无法理解该请求。 411 | 412 | 6.401 Unauthorized:由于缺乏目标资源要求的身份验证凭证,请求被拒绝。 413 | 414 | 7.403 Forbidden:服务器端有能力处理该请求,但是拒绝授权访问。 415 | 416 | 8.405 Method Not Allowed:当前HTTP请求的方法不合法。 417 | 418 | 9.406 Not Acceptable:服务器端无法提供与Accept-Charset以及Accept-Language指定的值相匹配的响应。 419 | 420 | 10.408 Request Timeout:服务器想要将当前连接关闭(没有在使用)。 421 | 422 | 一些服务器会在空闲链接上发送此信息,即便是在客户端没有发送任何请求的情况下。 423 | 424 | 11.500 Internal Server Error:所请求的服务器遇到以外的情况并阻止其执行请求。 425 | 426 | 12.501 Not Implemented:请求的方法不被服务器支持,因此无法被处理。 427 | 428 | 服务器必须支持的方法,只有GET和HEAD 429 | 430 | 13.502 Bad Gateway:作为网关或代理角色的服务器,从上游服务器(如tomcat)中接收到的响应是无效的。 431 | 432 | 14.503 Service Unavailable:服务器尚未处于可以接受请求的状态。 433 | 434 | 通常造成这种情况的原因是由于服务器挺急维护或者超载。 435 | 436 | -------------------------------------------------------------------------------- /9.HTTP(下).md: -------------------------------------------------------------------------------- 1 | ### 9.HTTP(下) 2 | 3 | 4 | 5 | #### 0.杂记 6 | 7 | JQuery没有引进来怎么办:按照下面操作,在重启服务。 8 | 9 |  10 | 11 | #### 1.涉及编码 12 | 13 | 1.对客户端提交过来的数据进行编码 14 | 15 | ```java 16 | // 对客户端提交的数据进行编码 17 | request.setCharacterEncoding("UTF-8"); 18 | ``` 19 | 20 | 2.响应(写)给浏览器的字符编码 21 | 22 | ```java 23 | response.setCharacterEncoding(“utf-8”); 24 | response.getWriter().write("