一、前言
本系列文章旨在复习计算机网络核心知识,进一步夯实基础,为以后 参与物联网、音视频、直播、即时通讯等领域的项目做一定的知识储备。
文章列表:
- 01-📝计算机网络核心知识|计算机网络通识【计算机网络性能指标、网络协议分层的几种方式、OSI七层模型概念通识】
- 02-📝计算机网络核心知识|【搭建调试环境、新建Java项目、计算机通信基础、计算机连接方式、集线器/网桥/交换机/路由器】
- 03-📝计算机网络核心知识|【MAC地址、IP地址的组成、IP地址的分类、CIDR、子网掩码、超网】
- 04-📝计算机网络核心知识|【 静态路由、动态路由、数据包的传输、ISP、服务器机房、网络分类、家用无线路由器、公网IP、
- 05-📝计算机网络核心知识|物理层/数据链路层【模拟信号&&数字信号、数据链路层】
- 06-📝计算机网络核心知识|网络层【IP数据包Packet、网络协议、Checksum、源IP地址和目标IP地址、ping】
- 07-计算机网络协议核心知识|【传输层-UDP】
- 08-计算机网络协议核心知识|【传输层-TCP之可靠传输】
- 09-📝计算机网络核心知识|传输层TCP2【流量控制原理、拥塞控制:slow start、congestion avoidance、快速重传、快速恢复】
- 10-计算机网络协议核心知识|【传输层-TCP连接】
- 11-计算机网络协议核心知识|【 应用层】
- 12-📝计算机网络核心知识|【Cookie、Session(概念、生命周期、有效期、浏览器的要求等)、跨域(概念、 同源策略、跨域解决方
- 13-计算机网络协议核心知识|【 代理/CDN/网络安全】
- 14-计算机网络协议核心知识|【(非)对称加密/数字签名/证书】
- 15-计算机网络协议核心知识|【HTTPS】
- 16-📝计算机网络核心知识|HTTPS协议【HTTP2、HTTP3】
本文假设你具备
HTML+CSS+JS+Java基础(知道基本语法及如何使用即可)。
二、搭建调试环境
要想真正了解网络之间数据如何传输?协议的约束条件?就需要一套能够发起网络请求和处理请求的环境。
1. 客户端
使用浏览器即可(会基本的HTML+CSS+JS即可)。
2. 服务端
以Java为例。
2.1 必装工具
- JDK:www.oracle.com/java/techno…
- Tomcat:tomcat.apache.org/
- Intellij IDEA Ultimate:www.jetbrains.com/idea/downlo…
运行Tomcat
Windows:
/tomcat-package/bin/startup.batMac或Linux:
/tomcat-package/bin/startup.sh
2.2 Java的跨平台原理
JVM(Java Virtual Machine):Java虚拟机。
Java跨平台:一次编译,到处运行。
- 编译生成和平台无关的字节码文件(
class文件) - 由对应平台的JVM解析字节码为机器指令(010101)
- 如果代码有语法错误,将编译失败,并不会生成字节码文件(失败后不会运行JVM程序,最终导致Java程序运行失败)
2.3 C/C++的跨平台原理
C/C++的跨平台:使用平台相关的编译器生成对应平台的可执行文件。
扩展:C++的是C Plus Plus的简写。
2.4 客户端和服务器交互
客户端发送网络请求给服务器,服务器使用Tomcat软件监听客户端发送的请求(含端口号),然后执行对应的Java代码把结果返给客户端。而字节码文件需要JVM运行环境才能正常运行(Tomcat本身也是Java编写的)。
3. 网络抓包工具
浏览器(Chrome、Firefox)、Fiddler、Wireshark、Charles
4. 模拟网络工具
用来模拟网络环境(交换机、路由器之间的切换)。
Xshell(只有Windows版本)、Packet Tracer(注册地址)、GNS3
三、新建Java项目并部署
我们自己搭建一个简单的登录页面和服务,以此了解客户端和服务端之间的数据交互流程。
提示:路径、类名、资源名尽量不要出现中文或者特殊字符。
1. 服务端(Java)
- 新建空项目
- 工程命名(工程名其实就是工程根目录文件夹名称)
- 新建模块(一个工程是由多个模块组成的)
- 在刚刚创建的模块src下新建一个java类(src是存放模块代码的)
- 运行
上面的配置只是单机运行,并没有任何客户端交互,我们可以建立一个JavaWeb服务器让HTML页面和服务器进行交互。
2. JavaWeb
- 添加Web框架支持,完成后会在模块中出现一个web文件夹
- 新建一个测试网页
要想通过浏览器直接访问网页,需要启动Tomcat并把项目部署到上面。
3. 启动tomcat
虽然可以直接在外面启动tomcat,但不是很方便。我们可以把tomcat集成到IDEA中,跟随项目启动和部署非常便捷。
- 编辑配置
- 添加tomcat服务
- 配置tomcat
- 运行(使用debug)
4. 访问资源
- 运行成功后IDEA会自动打开网址
http://localhost:8080/hello/,hello就是刚才上面配置的路径,默认访问index.htm/index.html/index.jsp其中一个。
也可以指定要访问的完整资源名。例如访问test.html:
- 如果web文件夹有变更,变更后不需要重启服务,只需要重新部署即可。
建议到配置文件中修该按钮默认事件为部署:
5. 登录
简单的登录界面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form action="/hello">
<div>用户名<input name="username"></div>
<div>密码<input name="password"></div>
<button type="submit">登录</button>
</form>
</body>
</html>
信息提交给服务器后,服务器如何处理呢?需要使用servlet,而tomcat有对应的库:jsp-api和servlet-api,把这两个库加入到项目中即可。
action后面直接拼接路径,就是根据项目所在服务器找对应资源。
6. servlet配置
由于已经在IDEA中集成了tomcat,只需要把tomcat的库添加到项目依赖。
6.1. 创建请求类
package com.idbeny.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
* 处理登录请求
* 1.继承HttpServlet(处理HTTP请求)
* 2.使用WebServlet(处理的请求路径)
*/
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
/**
* @param HttpServletRequest req 请求:用来获取客户端发送的数据
* @param HttpServletResponse resp 响应:用来给客户端返回数据
*/
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.获取客户端发送的数据(请求参数)
String username = req.getParameter("username");
String password = req.getParameter("password");
// 2.登录业务判断
if ("idbeny".equals(username) && "123456".equals(password)) {
// 登录成功
resp.getWriter().write("Login Success");
} else {
// 登录失败
resp.getWriter().write("Login Failure");
}
}
}
- 修改
login.html中的action:action="/hello/login" - 重新部署后并提交表单后输出
doGet,并且页面地址显示http://localhost:8080/hello/login?username=idbeny&password=123456,内容显示Login Success。 - 修改
method="post",重新部署后并提交表单后输出doPost,并且页面地址显示http://localhost:8080/hello/login,页面内容显示Login Success。表单参数可以通过浏览器的开发者工具看到。
Java中的包类似于C++中的命名空间。
四、计算机之间通信基础
计算机通信需要得知对方的IP地址,但最终是根据MAC地址(网卡地址),输送数据到网卡,被网卡接收。
- 如果网卡发现数据的目标MAC地址是自己,就会将数据传递给上一层进行处理(例如Java虚拟机)
- 如果网卡发现数据的目标MAC地址不是自己,就会将数据丢弃,不会传递给上一层进行处理
五、计算机之间的连接方式
可以通过Cisco Packet Tracer模拟网络连接。
1. 网线直连
两台计算机之间最简单的连接方式就是网线直连(交叉线)。
模拟通信的时候,会使用到ICMP、ARP协议。ping使用的是ICMP协议,ARP协议其实就是一个广播(ARP是有缓存的),让同一个网段中的指定IP响应当前计算机的网卡地址(广播找MAC地址)。
2. 同轴电缆
很早之前用的是半双工通信方式,特点是非常容易冲突(冲突域),不安全,只要断了全域瘫痪。因为一台设备在发送数据的时候,另一台设备只能接收数据,不能发送数据。现在基本上都是全双工通信,在接收数据的同时也可以发送数据。
3. 集线器(Hub)
采用的也是半双工通信,所以特点和同轴电缆一样,但仅仅比同轴电缆多一个优点:如果一台设备出现问题不会影响其他设备。
通过模拟通信看到,计算机0给计算机2发送数据的步骤如下:
- 计算机0发送数据给计算机2
- 首先发送ARP给集线器0,由集线器0转送ARP给连接设备(计算机1和计算机2),找寻IP对应的MAC地址
- 计算机1发现不是自己,就丢弃
- 计算机2发现要找的是自己(通过IP识别),然后把MAC地址等信息通过ARP发送给集线器0
- 集线器0又把数据转送给了其他的连接设备(计算机0和计算机1),
- 计算机0接收到数据后(MAC地址)开始使用ICMP传输
- 计算机1发现不是自己的数据,就丢弃
- 反复...
总结: 集线器和同轴电缆都是没有智商的,只要有设备发数据,就把数据转给其他所有已连接设备,设备越多效率越低。
4. 网桥(Bridge)
网桥连接的是同一个网段的计算机。
网桥能够通过自学习得知每个接口那侧的MAC地址,从而起到隔绝冲突域的作用(变成两个冲突域)
- 计算机0发送数据给计算机4,ARP结束后网桥0就会记录计算机0和计算机4的MAC地址,下次如果网桥左边的设备发送数据给计算机0时,网桥就会优先找右边的设备
- 如果计算机0发送给计算机1,由于集线器没有智商,也会发送给网桥0。网桥记录计算机0的MAC地址,并继续向下转发。下次网桥左边的设备发送数据给计算机1时,集线器0把数据转发给网桥0时,网桥发现已经记录的MAC地址对应的设备在左侧,就不会继续向下转发数据
5. 交换机(Switch)
网桥虽然解决了隔绝冲突域的问题。但同一个冲突域,还是不能互相同时收发数据。交换机的出现解决了该问题。
- 交换机相当于集线器和网桥的集合
- 全双工通信
- 比集线器安全(不会因为抓包而拦截数据)
首次发送数据时,还是会ARP广播所有设备,因为此时交换机还不知道源和目标的MAC地址。
思考:全球所有的设备都用交换机连接会是什么情况?
意味着都在同一个网段。首先产生的第一个问题就是IP地址不够用,其次如果使用ARP时,全球所有的设备都会收到该消息(广播风暴)。路由器的出现就是解决这个问题的。
6. 路由器(Router)
网线直连、同轴电缆、集线器、网桥、交换机的共同特点:
- 连接的设备必须在同一个网段
- 连接的设备处在同一个广播域
路由器的特点:
- 可以在不同网段之间转发数据
- 隔绝广播域
主机发数据之前,首先会判断目标主机的IP地址和它是否在同一个网段:
- 在同一个网段 通过交换机/集线器传递数据
- 不在同一个网段 通过路由器转发数据(网关)
交换机0和交换机1处于不同的网段,要想让不同网段之间通信,就需要在两个交换机之间增加一个路由器。
- 计算机4发送数据给计算机7时,先把发送ARP找到对应IP地址/网关
- 网关把数据转发给另一个网关(计算机7IP段的网关),找到计算机7后,再反向把MAC地址给到计算机4,此时即可开始数据传输
路由器是解决不同网段之间通信的,不要试图在同一个网段使用路由器(应该使用交换机)。
专题系列文章
1. 前知识
- 01-探究iOS底层原理|综述
- 02-探究iOS底层原理|编译器LLVM项目【Clang、SwiftC、优化器、LLVM】
- 03-探究iOS底层原理|LLDB
- 04-探究iOS底层原理|ARM64汇编
2. 基于OC语言探索iOS底层原理
- 05-探究iOS底层原理|OC的本质
- 06-探究iOS底层原理|OC对象的本质
- 07-探究iOS底层原理|几种OC对象【实例对象、类对象、元类】、对象的isa指针、superclass、对象的方法调用、Class的底层本质
- 08-探究iOS底层原理|Category底层结构、App启动时Class与Category装载过程、load 和 initialize 执行、关联对象
- 09-探究iOS底层原理|KVO
- 10-探究iOS底层原理|KVC
- 11-探究iOS底层原理|探索Block的本质|【Block的数据类型(本质)与内存布局、变量捕获、Block的种类、内存管理、Block的修饰符、循环引用】
- 12-探究iOS底层原理|Runtime1【isa详解、class的结构、方法缓存cache_t】
- 13-探究iOS底层原理|Runtime2【消息处理(发送、转发)&&动态方法解析、super的本质】
- 14-探究iOS底层原理|Runtime3【Runtime的相关应用】
- 15-探究iOS底层原理|RunLoop【两种RunloopMode、RunLoopMode中的Source0、Source1、Timer、Observer】
- 16-探究iOS底层原理|RunLoop的应用
- 17-探究iOS底层原理|多线程技术的底层原理【GCD源码分析1:主队列、串行队列&&并行队列、全局并发队列】
- 18-探究iOS底层原理|多线程技术【GCD源码分析1:dispatch_get_global_queue与dispatch_(a)sync、单例、线程死锁】
- 19-探究iOS底层原理|多线程技术【GCD源码分析2:栅栏函数dispatch_barrier_(a)sync、信号量dispatch_semaphore】
- 20-探究iOS底层原理|多线程技术【GCD源码分析3:线程调度组dispatch_group、事件源dispatch Source】
- 21-探究iOS底层原理|多线程技术【线程锁:自旋锁、互斥锁、递归锁】
- 22-探究iOS底层原理|多线程技术【原子锁atomic、gcd Timer、NSTimer、CADisplayLink】
- 23-探究iOS底层原理|内存管理【Mach-O文件、Tagged Pointer、对象的内存管理、copy、引用计数、weak指针、autorelease
3. 基于Swift语言探索iOS底层原理
关于函数、枚举、可选项、结构体、类、闭包、属性、方法、swift多态原理、String、Array、Dictionary、引用计数、MetaData等Swift基本语法和相关的底层原理文章有如下几篇:
- 01-📝Swift5常用核心语法|了解Swift【Swift简介、Swift的版本、Swift编译原理】
- 02-📝Swift5常用核心语法|基础语法【Playground、常量与变量、常见数据类型、字面量、元组、流程控制、函数、枚举、可选项、guard语句、区间】
- 03-📝Swift5常用核心语法|面向对象【闭包、结构体、类、枚举】
- 04-📝Swift5常用核心语法|面向对象【属性、inout、类型属性、单例模式、方法、下标、继承、初始化】
- 05-📝Swift5常用核心语法|高级语法【可选链、协议、错误处理、泛型、String与Array、高级运算符、扩展、访问控制、内存管理、字面量、模式匹配】
- 06-📝Swift5常用核心语法|编程范式与Swift源码【从OC到Swift、函数式编程、面向协议编程、响应式编程、Swift源码分析】
4. C++核心语法
- 01-C++核心语法|C++概述【C++简介、C++起源、可移植性和标准、为什么C++会成功、从一个简单的程序开始认识C++】
- 02-📝C++核心语法|C++对C的扩展【::作用域运算符、名字控制、struct类型加强、C/C++中的const、引用(reference)、函数】
- 03-📝C++核心语法|面向对象1【 C++编程规范、类和对象、面向对象程序设计案例、对象的构造和析构、C++面向对象模型初探】
- 04-📝C++核心语法|面向对象2【友元、内部类与局部类、强化训练(数组类封装)、运算符重载、仿函数、模板、类型转换、 C++标准、错误&&异常、智能指针】
- 05-📝C++核心语法|面向对象3【 继承和派生、多态、静态成员、const成员、引用类型成员、VS的内存窗口】
5. Vue全家桶
- 01-📝Vue全家桶核心知识|Vue基础【Vue概述、Vue基本使用、Vue模板语法、基础案例、Vue常用特性、综合案例】
- 02-📝Vue全家桶核心知识|Vue常用特性【表单操作、自定义指令、计算属性、侦听器、过滤器、生命周期、综合案例】
- 03-📝Vue全家桶核心知识|组件化开发【组件化开发思想、组件注册、Vue调试工具用法、组件间数据交互、组件插槽、基于组件的
- 04-📝Vue全家桶核心知识|多线程与网络【前后端交互模式、promise用法、fetch、axios、综合案例】
- 05-📝Vue全家桶核心知识|Vue Router【基本使用、嵌套路由、动态路由匹配、命名路由、编程式导航、基于vue-router的案例】
- 06-📝Vue全家桶核心知识|前端工程化【模块化相关规范、webpack、Vue 单文件组件、Vue 脚手架、Element-UI 的基本使用】
- 07-📝Vue全家桶核心知识|Vuex【Vuex的基本使用、Vuex中的核心特性、vuex案例】
6. 音视频技术核心知识
- 01-📝音视频技术核心知识|了解音频技术【移动通信技术的发展、声音的本质、深入了解音频】
- 02-📝音视频技术核心知识|搭建开发环境【FFmpeg与Qt、Windows开发环境搭建、Mac开发环境搭建、Qt开发基础】
- 03-📝音视频技术核心知识|Qt开发基础【
.pro文件的配置、Qt控件基础、信号与槽】 - 04-📝音视频技术核心知识|音频录制【命令行、C++编程】
- 05-📝音视频技术核心知识|音频播放【播放PCM、WAV、PCM转WAV、PCM转WAV、播放WAV】
- 06-📝音视频技术核心知识|音频重采样【音频重采样简介、用命令行进行重采样、通过编程重采样】
- 07-📝音视频技术核心知识|AAC编码【AAC编码器解码器、编译FFmpeg、AAC编码实战、AAC解码实战】
- 08-📝音视频技术核心知识|成像技术【重识图片、详解YUV、视频录制、显示BMP图片、显示YUV图片】
- 09-📝音视频技术核心知识|视频编码解码【了解H.264编码、H.264编码、H.264编码解码】
- 10-📝音视频技术核心知识|RTMP服务器搭建【流媒体、服务器环境】
7. 计算机网络核心知识
- 01-📝计算机网络核心知识|计算机网络通识【计算机网络性能指标、网络协议分层的几种方式、OSI七层模型概念通识】
- 02-📝计算机网络核心知识|【搭建调试环境、新建Java项目、计算机通信基础、计算机连接方式、集线器/网桥/交换机/路由器】
- 03-📝计算机网络核心知识|【MAC地址、IP地址的组成、IP地址的分类、CIDR、子网掩码、超网】
- 04-📝计算机网络核心知识|【 静态路由、动态路由、数据包的传输、ISP、服务器机房、网络分类、家用无线路由器、公网IP、
- 05-📝计算机网络核心知识|物理层/数据链路层【模拟信号&&数字信号、数据链路层】
- 06-📝计算机网络核心知识|网络层【IP数据包Packet、网络协议、Checksum、源IP地址和目标IP地址、ping】
- 07-计算机网络协议核心知识|【传输层-UDP】
- 08-计算机网络协议核心知识|【传输层-TCP之可靠传输】
- 09-📝计算机网络核心知识|传输层TCP2【流量控制原理、拥塞控制:slow start、congestion avoidance、快速重传、快速恢复】
- 10-计算机网络协议核心知识|【传输层-TCP连接】
- 11-计算机网络协议核心知识|【 应用层】
- 12-📝计算机网络核心知识|【Cookie、Session(概念、生命周期、有效期、浏览器的要求等)、跨域(概念、 同源策略、跨域解决方
- 13-计算机网络协议核心知识|【 代理/CDN/网络安全】
- 14-计算机网络协议核心知识|【(非)对称加密/数字签名/证书】
- 15-计算机网络协议核心知识|【HTTPS】
- 16-📝计算机网络核心知识|HTTPS协议【HTTP2、HTTP3】
其它底层原理专题
1. 底层原理相关专题
2. iOS相关专题
- 01-iOS底层原理|iOS的各个渲染框架以及iOS图层渲染原理
- 02-iOS底层原理|iOS动画渲染原理
- 03-iOS底层原理|iOS OffScreen Rendering 离屏渲染原理
- 04-iOS底层原理|因CPU、GPU资源消耗导致卡顿的原因和解决方案