OSI七层参考模型:
如图,说白了就是网络通信,就是两个人拿着电脑通信。
为什么要分层?
我们做编程的其实做的是软件工程学,里面有个重要的概念是分层解耦。
- 应用层:比如浏览器,tomcat,一些软件等等
- 表示层:协议,语义,字符串划分,加密等等这些
- 会话层:传输的控制,session等等,需要保持
- 传输控制层:主要是如何传输,如何连接,怎么确认连接成功还是失败的
- 网络层:设备当中如何去路游,如何找节点,如何通信,就是数据包怎么发
- 链路层:点与点之间应该使用什么协议通信,具体到应该写成什么样的东西发送过去
- 物理层:比如wifi,4G,光纤等等
TCP/IP协议
协议相当于根据OSI七层的参考模型一个具体的方案,具体的定义
TCP协议分为了这几个层,像七层模型里面的会话层和表示层都缩放到了应用层了
应用层:
比如http协议(浏览器访问),ssh协议(虚拟机访问)smtp协议(发邮件)
演示一个应用层协议
现在随便打开一个虚拟机的连接,一个连接界面,没有任何的浏览器,我现在要和百度进行连接,
windows上面的话可以使用浏览器,但我现在没有浏览器,因为这个不少浏览器,所以我请求百度回来的肯定是一堆html的标签
开始秀一把
cd 去到linux文件系统有个proc的目录,$$ 表示当前程序的进程id号,fd 是文件描述符,任何程序都有0、1、2,代表标准输入,输出,和报错输出,所以0、1、2是必须要有的
8<>
表示输入输出指向了连接百度80端口,在0、1、2 的后面新多出来一个文件描述符8
可以看到多出来一个socket套接字,表示通信已经建立好了,已经和百度进行连接了,然后开始传输http协议
把http协议规定的Request请求头里面最小的写法,\n表示识别换行符,输出内容重定向到文件描述符8,
也就是把这个内容发送给百度,回车之后就表示已经发送给百度了
既然发送给百度了,百度肯定会返回东西,cat表示读取,读取文件描述符8,也就是socket里面的东西给读取出来(中间时间不用浪费太久,不然连接太久了,读取会报错读取不到了)
通过这个可以知道:
第一步建立连接
第二步才是传送数据(http协议:规范标准)
这个demo是应用层协议,每一层都有自己的协议
虽然我们在windows上面使用浏览器访问百度,都是输入地址直接回车就可以了,其实浏览器肯定在后面帮我们做了这个
查看返回的
和纯手工演示的也是一样的
以上我们看到的都是应用层的东西,也就是在用户态的,从传输控制层开始,是服务器内核态的,请求一次百度到服务器后,经过了传输控制层-> 网络层-> 链路层-> 物理层,然后再返回到应用层的。
传输控制层
传输控制层的协议有TCP和UDP协议,有什么区别呢?
TCP协议是面向连接的,可靠的,UDP是刚好相反的,它不是面向连接的,所以不是可靠的。
什么是面向连接?
说白了,就是需要确认的连接,每次连接都是已经确认了的连接,所以肯定是可靠的。
所以有了3次握手和4次挥手的概念。
3次握手
比如客户端在请求百度的时候,在传输控制层这里的时候,传输控制层给百度服务器发送数据包进行连接。
客户端第一次进行与服务器的连接,服务器会给客户端回应连接请求,然后客户端开始进行连接,这样就已经非常明确要建立连接,所以一次连接就建立成功,这样的连接当然是非常可靠的,因为中间还有了确认过程。
3次数据包走完以后,双方才会在内存开辟线程,开辟对象,开辟所有的描述符,如果3次握手没完成,这些资源不会开辟的。
4次分手
为什么会有4次分手?
一台电脑上有65535个端口,看着好像很大,但当你随便打开一个百度连接,在控制台就可以看到会有很多的连接。这里不要有误解:你向外访问的端口号有65535个,但别人进来访问的话是你的一个端口号,也就是百度拿着一个80端口相应几十万的qps。但一台电脑如果想同时访问10w(大于65535)个连接,是肯定建立不起来的。
所以我们写代码时候总会说不要忘记关闭连接,当不再使用一个端口时候,还在占用这个端口,那其他服务跟这个端口是肯定建立不起来连接的,所以一定要有分手的事断开连接。
为什么分手断开连接是4次?
首先客户端请求服务端说要断开连接,服务端会响应给客户端说:"好,我知道了,你想断开连接",这个时候肯定不能就直接断开连接。
因为这个时候如果服务端还有数据给客户端传输数据,肯定不能断开。
但如果服务端这时候可以断开连接,就会再次响应给客户端:"我也想断开连接了",然后客户端会再告诉服务端:"行,我也知道了"。
所以在双方都想断开连接时候,等一个合适的时间片,就断开连接,不会有什么影响。
使用netstat -natp
命令可以查看服务端对客户端连接过来的ip和端口做的处理
所以这一层叫传输控制层,3次握手时候,在最后一次握手时候把确认连接和输出的数据包都给顺便放在第3次握手请求给服务端了。
网络层
网络层主要是有一个下一跳机制的概念,主要是找到对应的下一跳网关地址
通过命令route -n
可以查到路由判定
它是位运算,使用的与运算
ping通百度,可以看到百度的ip是45.113.192.102
,结合路由判定来看,如果和0.0.0.0
进行与运算,得到的结果还是0.0.0.0
,所以会走网关10.10.10.2
如果和255.255.255.0
进行与运算,得到的结果肯定不是10.10.10.0
,所以匹配不上,就会跳到下一个匹配寻找对应的网关
再试一下ping通qq,道理还是一样的
可以看到找到的都是10.10.10.2
这个网关地址,可我访问的是百度的ip地址45.113.192.102
,是怎么访问到这个百度的ip地址的?
这个是下一层链路层要做的事情,网络层主要是找到对应的下一跳网关地址
链路层
在网络层通过下一跳机制找到对应的网关地址后,链路层通过网关地址,映射到了网卡的mac地址
每一层都有对应的表,链路层对应的表通过命令arp -a
查看
可以看到网关地址10.10.10.2
对应的mac地址是00:50:56:f4:b8:e1