写点什么

Week8

用户头像
关注
发布于: 2020 年 07 月 29 日

数据结构和算法


网络通信协议



OSI 协议七层模型:

每一层都只关注自己关注的东西,把每一层的职责功能共同叠加,构建出整个通讯协议。

物理层:物理层关注的是物理媒介上传输的二进制格式,数据传输本质就是 0 和 1。如何定义 0 和 1,让无线设备发出的电波和光缆中传输的光信号,能相互识别、传输,这是物理层关注的东西。定义的是物理媒介上数据相互识别的规则。

数据链路层:核心职责是地址,无数的网络设备,手机、电脑、很多移动设别。如何知道你的信息要发送到哪一台设备上?对于 tcp 协议来说,其实就是对应设备的 mac 地址。还有一些错误检测,及流量控制,都是在链路层做的事情。

网络层:主要做路由选择。

传输层:提供端对端的接口。常用 tcp、udp 协议。服务器上运行着很多进程,由哪一个进程,去处理用户的请求?由传输层决定。数据包到了服务器以后,如果发送的 web 请求,默认发送到 80 端口,服务器交给监听 80 端口的进程来处理请求。

会话层:保持会话连接

表示层:数据是以字节流的方式传递的。收到数据以后,数据格式转换,加密、解密、压缩、解压缩都在表示层处理。

应用层:把以上一切,打包成一个接口,供给用户使用。


TCP/IP 四层模型:

应用层协议:http

传输层:tcp、udp

网络互联层:IP 协议,由 IP 地址实现网络分发

网络访问链路层:链路协议

网络数据包格式:

示例:

如 A 向 B 发送一段 json 数据,先由 http 协议包装为 http 格式的数据,再交由下一层,依赖 tcp 协议,包装为 tcp 格式,再交由下一层,包装为网络层的包,再交由下一层,包装为网络链路层格式的包。然后通过物理网络传输到 B 服务器。B 接收到后,一层一层拆包。网络链路层拆包后,拿到的是 IP 的数据。网络层拆包后,拿到的是传输层的数据。这时候检查,你要访问的端口是哪个,调用对应监听端口的进程来处理这段数据。在拆包后,得到的就是 http 的包。再拆包,就得到了发送的 json 数据。

可靠的 TCP 协议:

ip 协议不是一个可靠的通信协议,不会建立稳定的通信链路,不会确保数据一定送达。保证通讯可靠,必须依赖传输层协议 tcp。

tcp 协议是一个面向连接的、可靠的、基于字节流的传输层协议。tcp 作为一个比较基础的通讯协议,有很多重要的机制,保证了 tcp 协议的可靠性。

1.使用序号,对收到的 tcp 报文进行排序和检测重复数据

2.无错传输,使用校验和检测报文段的错误

3.使用确认和计时器来检测和纠正丢包或者延时

4.流量控制,避免主机发送过快而使接收方来不及完全收下

5.拥塞控制,发送方根据网络承载情况控制分组的发送量,以获得高性能同时避免拥塞崩溃丢失包重传

tcp 建立连接三次握手:

tcp 关闭连接四次挥手:

http 协议是为应用程序服务的,同样层级著名的协议还有 ftp 协议。

应用层 http 协议:

7 种方法:

get、post、delete、put、head、trace、options

响应 5 种状态:

1xx:消息已被服务器接收,正在处理

2xx:成功

3xx:重定向,需要后续操作才能完成本次请求

4xx:请求错误,请求含有语法错误

5xx:服务端错误,服务器内部发生异常

http 协议版本:

1.0:客户端-服务端,每次会话都会三次握手,四次挥手。频繁创建销毁链接。握手时间是算请求延迟的,挥手不算。

1.1:默认启用长连接模式,客户端可以使用一个 tcp 链接顺序发送多个请求,新版本也引入了管道机制,客户端可以不用等上一次请求返回的结果,就发送下一个。但是服务端还是按照客户端请求的顺序依次响应。可以理解为半双工模式。

http/2:和复用 tcp 链接模式不同。依然遵循请求-响应模式。但客户端发送多个请求,和服务端给出多个响应顺序不受限制,这样避免了“队头堵塞”,又能更快获取响应。




非阻塞网络 IO

socket 连接的基本概念:

当服务端启动后,会有一个程序,调用操作系统暴露的 socket 接口,bind 某个端口。操作系统使当前线程,监听该端口。有人连接后,程序调用 accept 方法,来读取 tcp 拆包后的数据。这个时候要注意,第一个连接的程序,这里会出现两个 socket。一个是客户端和服务端建立连接的 socket。一个是服务器程序自己 new 出来的监听服务器端口的 socket。

这里,accept 的时候,这里就开始监听,等待客户端连接,这里就发生了阻塞。socket.getInputStream().read()。这里如果数据没有全部传过来,还是要发生等待,阻塞。socket.getOutputStream().write()。传回数据调用 write 方法。socket 内存大小是有限的,很可能会占满,所以写的时候也可能阻塞。

如何解决?使用多线程

主线程来 accept,只用于建立连接。read 和 write 的操作由下面子线程完成。如果阻塞,只阻塞单个线程。

阻塞 IO:



物理介质,发送网络包给网卡,网卡解析链路层数据包,判断 mac 地址是否是本机。

交给操作系统,IP 地址包裹 tcp 数据包。

操作系统处理完以后,将 tcp 数据部分,写到 socket 缓冲区。

等待线程来 read。

(将网卡中的数据写到 socket 缓冲区,是操作系统完成的。完成这一操作后,会唤醒线程来处理。当线程写的时候,写到 socket 发送缓冲区,发完后,操作系统调用来发送数据到网卡,然后发出去。缓冲区满写不进去,会阻塞,缓冲区空,读不到数据,也会阻塞。都会阻塞应用线程。应用来说,只有这两个阻塞点(网络部分))


非阻塞 IO:


数据库


总结尚未完成。。。

用户头像

关注

还未添加个人签名 2018.05.02 加入

还未添加个人简介

评论

发布
暂无评论
Week8