网络基础
网络与 IP
前面说了,请求和响应都是遵循 HTTP 协议的,HTTP 只是规定了请求和响应时那 4 个部分怎么写,但它没有规定怎么传。
HTTP 协议的底层其实是由 TCP 协议和 IP 协议构建的,简单的说,TCP 协议规定了怎么传输,IP 协议规定了怎么联网。
TCP 传输控制协议 (Transmission Control Protocol)
TCP 和 UDP 的区别是什么
TCP 可靠(我发一个请求,成功与否我是知道的)、面向连接、相对 UDP 较慢
UDP 不可靠,不面向连接、相对 TCP 较快
TCP 的三次握手指的是什么
每次建立连接前,客户端和服务端之间都要先进行三次对话才开始正式地传输内容,三次对话大概是:1. 客户端:我要连接你了,可以吗 2. 服务端:嗯,我准备好了,连接我吧 3. 客户端:那我连接你咯 4. 开始后面步骤
IP 网络协议(Internet Protocol)
只要你在互联网中,那么你就会有一个 IP
通俗上理解,IP 分为内网 IP 和外网 IP,如图
- 你从电信那里买来带宽
- 电信为你提供 DNS 服务(最基础的域名 IP 服务,我们上网是基于 TCP/IP 协议的,没 IP 啥也做不了)
- 你买了个路由器并把路由器连上网线,只要路由器连上了电信的服务器,那么路由器就会有一个外网 IP,比如‘13.18.36.210’,这也就是你在互联网中的地址
- 但如果你重启了你的路由器,那么路由器很可能会被重新分配一个外网 IP,也就是说你的路由器没有固定的外网 IP
- 当然,如果你不怕浪费钱的话可以租用一个固定的外网 IP,像腾讯、阿里这样的大公司租用了很多外网 IP 才能为我们提供稳定的服务
- 你用手机电脑连接上了路由器释放的无线 WIFI,那么你手机电脑的 IP 就是内网 IP
- 路由器会在你的家里创建一个内网,内网中的设备使用内网 IP,一般这个 IP 的格式为:192.168.xxx.xxx
- 一般路由器会给自己分配一个好记的内网 IP:192.168.1.1
- 然后路由器会个每一个内网中的设备分配一个不同的内网 IP,比如:电脑(192.168.1.2)、手机(192.168.1.3)...
- 也就是说,路由器拥有 2 个 IP,一个外网 IP(13.18.36.210)、一个内网 IP(192.168.1.1)
- 内网中的设备可以互相访问,比如你可以在电脑或者手机上访问 http://192.168.1.1 来查看配置路由器,但是不能直接访问外网,内网设备想要访问外网,必须通过路由器的中转
- 外网中的设备可以互相访问,比如 www.baidu.com 可以把首页发送到你的路由器,你的路由器有外网 IP,但外网设备无法访问内网设备,内网是一个封闭的网络,实际上 www.baidu.com 是无法直接把首页发送到你的手机和电脑的,那么手机电脑是怎么访问百度首页的呢
- 路由器接收 www.baidu.com 首页页面之后,将其发送到手机电脑,路由器知道如何给这些信息指路,这也是路由的由来
- 综上所述,内网和外网是两个隔绝的空间,无法互通,它们之间唯一的联通点就是路由器,因为路由器既有外网 IP 也有内网 IP,所以有些时候它也被叫做网关,因此如果路由器与电信之间的连接中断了,那么内网中的所有设备都无法上网了
两个特殊 IP
1. 本地 IP:127.0.0.1,永远指向设备自身,在 hosts 文件中 localhost 指向 127.0.0.1,即 localhost 也表示设备自身
2. 特殊 IP:127.0.0.0,不表示任何设备,此 IP 不同的地方含义不同
端口
- 访问一个设备(前提是你使用是 TCP/UDP 协议),仅仅是指定 IP 是不够的,还必须指点端口,端口是一个编号,并不是一种硬件
- 一个服务器(硬件)不一定只提供一中服务(那样太浪费了),比如一个服务器既提供了 HTTP 服务,又提供了 FIP 服务,还提供了 SMIP 服务,那么只使用 IP 是无法告诉服务器你想要使用哪种服务的
- 一个端口对应一个服务,否则效率会很低,比如一个端口来了三个不同服务的请求,那么后面两个就需要等待
- 每个机器一共拥有 65535 个端口(协议规定),0-1023 号端口号预留给系统使用,只有管理员身份才能使用,其他端口可以给普通用户使用
- 如果一个端口正在提供服务,即被占用了,那么就不能再使用这个端口,除非你先停掉占用这个端口的服务
- 使用 HTTP 协议访问一个 IP时,必须同时提供 IP 和端口号,但我们常常访问 http://www.baidu.com 并没有加端口号,是因为浏览器默认帮你加了端口号
一个简单的 Server
前面了解了这么多基础知识,现在我们来搞一个服务器吧,然后提供 HTTP 服务
- (硬件)服务器你已经有了,也就是你的电脑,实际上服务器与电脑没有多大区别,只是它没有像电脑提供的多样化体验的硬件比如显示器、显卡,所以更加稳定,那么怎么操作它呢,答案是使用 SSH 远程登录,有网、CPU 性能强大、内存容量大,实际上它还是个电脑
- (软件)但你没有提供 HTTP 服务的程序,其实用脚本就可以提供 HTTP 服务,不管是 Bash 脚本还是 Node.js 脚本都可以,然而 Bash 语法反人类所以下面我们要通过 Node.js 脚本来提供 HTTP 服务,下面的代码语法不要求弄懂,重点是服务器的运行过程
- git bash ==> 命令行 ==> 脚本 ==> Node.js 本质上也是脚本 ==> 写一个 Node.js server 以了解什么是服务器以及服务器的运行过程
Node.js 服务器
脚本只需要一个文件就行了
- 新建一个安全的目录
cd ~/Desktop mkdir node-demo cd node-demo touch server.js
编辑 server.js(只需要看中间的三行,其他代码照抄即可)
- 运行 node server.js,看到报错
- 根据报错提示调整你的命令
- 成功之后,这个 server 会保持运转,无法退出
- 如果你想要中断这个 server ,Ctrl + C,中断之后才能输入其他命令,所以建议把这个 server 放那别动,新开一个 Bash 窗口,继续下面步骤
- 目前我们只做一个功能,接下来你要发送一个请求到这个服务器,“自己向自己发起请求”,是的,因为咱没有服务器啊
- 在新的 Bash 窗口(其实这个 Bash 窗口相当于浏览器)运行
curl http://localhost: 你的指定的端口/xxx 或者 curl http://127.0.0.1: 你的指定的端口/xxx
- 你会发现 server(即运行 server.js 的 Bash 窗口)打印出了路径,这说明了什么,说明服务器收到了我们用 curl 发的请求
- 这个服务器目前只有一个功能,那就是接收请求并打印出路径和查询字符串,还缺少一个重要的功能,就是发出 HTTP 响应
- 而服务器脚本程序中目前只有三行打印路径功能的代码,即没有响应的代码,所以 curl 接收不到响应,而这边服务器在等待你的下一次请求,双方互相等待
- 使用
Ctrl + C
能中断 curl 或 server- 接下来编辑 server.js 文件让 server 接收请求时会发出响应,只需要在三行代码下面添加
response.write('Hi !!!') response.end()
- 中断之前的 server 重新运行
node server.js 9999
curl http://localhost:9999/xxx
就能看到 Hi !!! 表明 server 可以响应请求,你甚至可以运行curl -s -v -- "http://localhost:9999/xxx"
查看详细信息接下来我们将 server 响应信息更改成一个完整的页面(包含html/css/js),将之前的 server 中的 5 行代码替换为:
- 整体逻辑是:如果请求路径是 /css,就会给页面加上 css;如果请求路径是 /js,就会执行 JS 代码弹窗;如果请求路径是 /index,就会加载整个 html 页面;其他情况显示 404错误
- 事实上,我们一般不会直接请求 /css 或 /js 路径,具体在浏览器中一般会请求 /index 来请求 html 页面,而当浏览器得到响应的 html 代码并下载解析时,会遇到 link、script 标签,接着再向服务器请求相应的资源并下载解析执行
response.setHeader()
是设置 Content-Type 和 字符编码的,Content-Type 会让浏览器根据你甚至的格式来解析,比如如果没有设置 /index 路径的 HTML 页面的为 Content-Type,那么就不会显示你好,而是显示具体的 html 代码;而charset=utf-8
设置了字符编码为 utf-8 致使能渲染中文