目录
1、蜂窝移动网络
2、TCP和UDP
3、5层架构
4、在浏览器中输入url地址à显示主页的过程
5、TCP的基本操作
6、三次握手,四次挥手
6.1、三次握手:双方保证自己和对方都能接收和发送数据。
6.2、三次握手中,为什么客户机最后还要再向服务器发送一次确认呢?
6.3、SYN攻击是什么?
6.4、四次挥手
6.5、为什么连接的时候是三次握手,关闭的时候却是四次握手?
6.6、为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
6.7、如果已经建立了连接,但是客户端突然出现故障了怎么办?
7、TCP为什么不一次发送完所有数据
8、数据拆包和粘包
9、TCP协议如何恢复数据的顺序
10、滑动窗口和流速控制
11、路由和寻址的区别
11.1、第一步:IP协议
11.2、第二步:寻址
11.3、第三步:路由
12、localhost、127.0.0.1和0.0.0.0和本机IP的区别
13、IPV4和IPV6
14、Tunnel技术
15、NAT(网络地址解析协议)解决内外网通信问题
15.1、NAT如何连接内外网
15.2、对于一个网络接口,如何能知道目标接口的 MAC 地址
16、Socket
16.1、Socket是什么
16.2、Socket的原理
16.3、IO多路复用
16.4、Epoll为什么用红黑树
16.5、三种IO多路复用模型
16.6、总结
1、蜂窝移动网络
网络从本地网络服务提供商 (Internet Service Provider) 接入,然后内部再分成一个个子网,数据传输的线路,被称为通信链路。
有的网络节点,同时接入了 2 条以上的链路,这个时候因为路径发生了分叉,数据传输到这些节点需要选择方向,因此我们在这些节点需要进行交换(Switch)。
网络中的数据是以分组或封包(Packet)的形式传输,因此这个技术也称作封包交换技术(如果一个封包损坏,只需要重发损坏的封包,而不需要重发所有数据)。
2、TCP和UDP
- UDP
核心在于灵活。不可靠。传送数据前无需建立连接,远地主机收到数据后,不需要给出任何确认。一般用于及时通信:QQ语音,QQ视频、直播等。
- TCP
核心在于可靠性。传输层协议,全双工,面向连接,传送数据前需要建立连接,数据传输结束后需要释放连接。三次握手、四次挥手。常用于文件传输、发送和接收邮件、远程登录等。
3、5层架构
- 应用层:提供应用到应用的协议,应用之间进行通信时,会将通信方的IP和端口号告知传输层。
- 传输层:TCP,把 IP 地址给底层的互联网层处理。
- 网络层:提供IP地址到地址的通信,调用链路层。
- 链路层:在两个相邻设备间传递信息。
- 物理层:封装最底层的物理设备,传输介质。
4、在浏览器中输入url地址->显示主页的过程
DNS解析:将域名指向网站空间IP
TCP连接
发送HTTP请求
服务器处理请求并返回HTTP报文
浏览器解析渲染页面
连接结束
5、TCP的基本操作
如果一个 Host 主动向另一个 Host 发起连接,称为 SYN(Synchronization),请求同步;
如果一个 Host 主动断开请求,称为 FIN(Finish),请求完成;
如果一个 Host 给另一个 Host 发送数据,称为 PSH(Push),数据推送。
6、三次握手,四次挥手
TCP标志位:SYN(建立连接)、ACK(确认)、ISN(序列号)
6.1、三次握手:双方保证自己和对方都能接收和发送数据。
- 第一次握手:客户端向服务端发送SYN(1bit)标志和一个随机序号(4 byte)seq=x。
服务端确认对方发送正常,自己接收正常。
- 第二次握手:服务端向客户端发送ACK(1bit)标志、SYN标志和一个随机序号seq=y、ack=x+1。
客户端确认自己发送、接收正常,对方发送、接收正常;
- 第三次握手:客户端向服务端发送ACK标志和随机序号seq=x+1、ack=y+1。
服务端确认自己发送正常,对方接收正常。
-
6.2、三次握手中,为什么客户机最后还要再向服务器发送一次确认呢?
-
防止已失效的连接请求报文突然又传到了服务器。
客户端发送第一次请求,但由于滞留在某个节点,并未收到服务端的确认报文。所以客户端重发,第二次发送请求,并且完美建立连接,传输数据,最后释放连接。此时,第一次发送的报文段,到了服务端,且服务端发送了确认报文。如果没有第三次握手,此时就又建立了连接,但客户端并没有数据发往服务端,连接就会一直持续,消耗网络资源。
-
6.3、SYN攻击是什么?
-
SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存在,因此Server需要不断重发直至超时,这些伪造的SYN包将长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。SYN 攻击是一种典型的 DoS/DDoS 攻击。
检测 SYN 攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以使用系统自带的 netstats 命令来检测 SYN 攻击。
netstat -n -p TCP | grep SYN_RECV
常见的防御 SYN 攻击的方法有如下几种:
缩短超时(SYN Timeout)时间
增加最大半连接数
过滤网关防护
SYN cookies技术 -
6.4、四次挥手
-
TCP标志位:FIN(断开连接)
TCP是双工的,不同方向的连接独立
-
- 第一次挥手:客户端发送FIN(断开连接请求)报文和序列号seq=u(已经传送过来的数据的最后一个字节的序号加1),用来关闭客户端到服务端的数据传送。
我客户端没有数据给服务端了,但你服务端如果还有数据,可以继续发。
- 第二次挥手:服务端发送ACK(确认)报文和ack=u+1序列,针对客户端的FIN的确认应答。
我服务端收到你的请求了,但我还没准备好断开连接,请稍等。
-
第三次挥手:服务端发送FIN报文和seq=w序列号,用来关闭服务端到客户端的数据传送。
我服务端没有数据给客户端了,准备关闭连接了。
-
第四次挥手:客户端发送ACK报文和ack=w+1序列,针对服务端的FIN的确认应答。
我客户端收到你的请求了,即将断开连接。
6.5、为什么连接的时候是三次握手,关闭的时候却是四次握手?
因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
6.6、为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
2MSL:一个发送和一个回复所需的最大时间。
为了保证服务端已经收到客户端发送的ACK确认报文。
服务端发送FIN报文后,如果没有收到ACK,将会不断重复发送FIN。TIME_WAIT状态就是为了接收服务端重发的FIN报文。
考虑一种情况,如果客户端最后发送的ACK在网络传输中丢失了,服务端自然就不会收到客户端回应的ACK报文,此时服务端会重发FIN,客户端在重新接收到FIN后,会重置TIME_WAIT时间,并重新发送一个ACK报文给服务端,表明自己收到了FIN断开连接请求。而如果客户端在2MSL时间内没有再次收到服务端发送的FIN,说明服务端已经收到ACK确认报文,此时客户端就可以设置状态为CLOSE了,结束TCP连接。
6.7、如果已经建立了连接,但是客户端突然出现故障了怎么办?
TCP有一个保活计时器。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
7、TCP为什么不一次发送完所有数据
稳定:数据量越大,出错的概率就越大。
效率:封包并行发送,效率更高。
TCP将数据拆分成不超过缓冲区大小的一个个部分,每部分叫做一个TCP段。
8、数据拆包和粘包
- 拆包
数据被拆分为很多个部分,部分增加了协议头,合并成一个TCP段(带序号保证顺序),进行传输。可降低整体任务出错的概率,减小底层网络处理的压力。
- 粘包
防止数据量过小,导致大量的传输,而将多个 TCP 段合并成一个发送。
9、TCP协议如何恢复数据的顺序
TCP 利用(发送字节数、接收字节数)的唯一性来确定封包之间的顺序关系。
10、滑动窗口和流速控制
滑动窗口是 TCP 协议控制可靠性的核心。发送方将数据拆包,变成多个分组。然后将数据放入一个拥有滑动窗口的数组,依次发出,仍然遵循先入先出(FIFO)的顺序,但是窗口中的分组会一次性发送。窗口中序号最小的分组如果收到 ACK,窗口就会发生滑动;如果最小序号的分组长时间没有收到 ACK,就会触发整个窗口的数据重新发送。
另一方面,在多次传输中,网络的平均延迟往往是相对固定的,这样 TCP 协议可以通过双方协商窗口大小控制流速。
将已发送的数据放到最左边,发送中的数据放到中间,未发送的数据放到右边。假设我们最多同时发送 5 个封包,也就是窗口大小 = 5。窗口中的数据被同时发送出去,然后等待 ACK。如果一个封包 ACK 到达,我们就将它标记为已接收(深绿色)。
- 有两个封包的 ACK 到达,因此标记为绿色
- 这个时候滑动窗口可以向右滑动
- 如果发送过程中,部分数据没能收到 ACK 会怎样呢?这就可能发生重传。
- 这个时候滑动窗口只能右移一个位置
在这个过程中,如果后来段 4 重传成功(接收到 ACK),那么窗口就会继续右移。如果段 4 发送失败,还是没能收到 ACK,那么接收方也会抛弃段 5、段 6、段 7。这样从段 4 开始之后的数据都需要重发。
11、路由和寻址的区别
11.1、第一步:IP协议
接收Host-To-Host协议传来的数据,然后进行拆分(数据太大不适合网络传输),并为每个片段增加一个IP头,组成一个IP封包,然后通过链路层进行数据传输。
11.2、第二步:寻址
根据IP地址找到设备。根据IP和子网掩码逐级找到网络,最后定位设备。
11.3、第三步:路由
网络和网络间是网关在连接,因此如果目的地 IP 不在局域网中,就需要为 IP 封包选择通往下一个网络的路径,其实就是选择其中一个网关。
路由(Routing)本质是路径的选择。就好像知道地址,但是到了每个十字路口,还需要选择具体的路径。
12、localhost、127.0.0.1和0.0.0.0和本机IP的区别
- localhost
localhost其实是域名,一般windows系统默认将localhost指向127.0.0.1,但是localhost并不等于127.0.0.1,localhost指向的IP地址是可以配置的。
- 127.0.0.1
凡是以127开头的IP地址,都是回环地址。就是我们在主机上发送给127开头的IP地址的数据包会被发送的主机自己接收,根本传不出去,外部设备也无法通过回环地址访问到本机。
- 0.0.0.0
首先,0.0.0.0是不能被ping通的。在服务器中,0.0.0.0并不是一个真实的的IP地址,它表示本机中所有的IPV4地址。监听0.0.0.0的端口,就是监听本机中所有IP的端口。
13、IPV4和IPV6
切片->增加封包头->路由->寻址。
两者都是接收上方主机到主机(Host-to-Host)协议传递来的数据,比如一个 TCP 段(Segment),然后将 TCP 段再次切片做成一个个的 IPv6 封包(Datagram or Packet),再调用底层局域网能力(数据链路层)传输数据。
IPv4 的地址是 4 个 8 位(octet),总共 32 位。 IPv6 的地址是 8 个 16 位(hextet),总共 128 位。
14、Tunnel技术
隧道。两个网络,用隧道连接,位于两个网络中的设备通信,都可以使用这个隧道。隧道是两个网络间用程序定义的一种通道。具体来说,如果两个 IPv6 网络被 IPv4 分隔开,那么两个 IPv6 网络的出口处(和 IPv4 网络的网关处)就可以用程序(或硬件)实现一个隧道,方便两个网络中设备的通信。
15、NAT(网络地址解析协议)解决内外网通信问题
网络地址解析协议(NAT)解决的是内外网通信的问题,是IPV4资源耗尽的主流解决方案。NAT 通常发生在内网和外网衔接的路由器中,由路由器中的 NAT 模块提供网络地址转换能力。
从设计上看,NAT 最核心的能力,就是能够将内网中某个 IP 地址映射到外网IP,然后再把数据发送给外网的服务器。当服务器返回数据的时候,NAT 又能够准确地判断外网服务器的数据返回给哪个内网 IP。
- 交换机,或者称为链路层交换机,通常工作在链路层;而路由器通常也具有交换机的能力,工作在网络层和链路层
- 设备间通信的本质其实是设备拥有的网络接口(网卡)间的通信。
- IP地址是可变的,而每台电脑网卡的MAC地址是独一无二的。
- 数据的发送方,将自己的 MAC 地址、目的地 MAC 地址,以及数据作为一个分组(Packet),也称作 Frame 或者封包,发送给交换机。交换机再根据目的地 MAC 地址,将数据转发到目的地的网络接口(网卡)。
15.1、NAT如何连接内外网
- NAT 需要作为一个中间层替换 IP 地址。 发送的时候,NAT 替换源 IP 地址(也就是将内网 IP 替换为出口 IP);接收的时候,NAT 替换目标 IP 地址(也就是将出口 IP 替换回内网 IP 地址)。
- NAT 需要缓存内网 IP 地址和出口 IP 地址 + 端口的对应关系。也就是说,发送的时候,NAT 要为每个替换的内网 IP 地址分配不同的端口,确保出口 IP 地址+ 端口的唯一性,这样当服务器返回数据的时候,就可以根据出口 IP 地址 + 端口找到内网 IP。
15.2、对于一个网络接口,如何能知道目标接口的 MAC 地址
ARP缓存目标IP对应MAC地址,地址解析协议通过广播找到IP对应MAC地址。
- 如果一个网络接口已经知道目标 IP 地址对应的 MAC 地址了,它会将数据直接发送给交换机,交换机将数据转发给目的地
- 如果网络接口不知道目的地地址呢?则会使用到地址解析协议。发送接口会发送一个广播查询给到交换机,交换机将查询转发给所有接口。如果某个接口发现自己就是对方要查询的接口,则会将自己的 MAC 地址回传。接下来,会在交换机和发送接口的 ARP 表中,增加一个缓存条目。也就是说,接下来发送接口再次向 IP 地址 2.2.2.2 发送数据时,不需要再广播一次查询了。
16、Socket
16.1、Socket是什么
Socket 首先是文件,存储的是数据。
对服务端而言,分成服务端 Socket 文件和客户端 Socket 文件。
服务端 Socket 文件存储的是客户端 Socket 文件描述符(每个客户端接入之后会形成一个客户端的 Socket 文件);客户端 Socket 文件存储的是传输的数据。
读取客户端 Socket 文件,就是读取客户端发送来的数据;写入客户端文件,就是向客户端发送数据。对一个客户端而言, Socket 文件存储的是发送给服务端(或接收的)数据。
16.2、Socket的原理
ServerSocket绑定端口,定期扫描服务端Socket文件变更,如果读取到客户端的文件描述符,则会将该文件描述符实例化为Socket对象。
16.3、IO多路复用
- 命令式
服务端程序(线程)需要维护一个 Socket 的集合(可以是数组、链表等),然后主动定期遍历这个集合。
- 响应式
某个观察者(操作系统)会观察到 Socket 文件状态的变化,从而通知处理线程响应。线程不再需要遍历 Socket 集合,而是等待观察程序的通知。
16.4、Epoll为什么用红黑树
中间观察者最核心的诉求有两个:
- 第一个核心诉求,是让线程可以注册自己关心的消息类型。比如线程对文件描述符 =123 的 Socket 文件读写都感兴趣,会去中间观察者处注册。当 FD=123 的 Socket 发生读写时,中间观察者负责通知线程,这是一个响应式的模型。
- 第二个核心诉求,是当 FD=123 的 Socket 发生变化(读写等)时,能够快速地判断是哪个线程需要知道这个消息。
所以,中间观察者需要一个快速插入(注册过程)、查询(通知过程)一个整数的数据结构,这个整数就是 Socket 的文件描述符。
16.5、三种IO多路复用模型
(轮询)select 是一个主动模型,需要线程自己通过一个集合存放所有的 Socket,然后发生 I/O 变化的时候遍历。在 select 模型下,操作系统不知道哪个线程应该响应哪个事件,而是由线程自己去操作系统看有没有发生网络 I/O 事件,然后再遍历自己管理的所有 Socket,看看这些 Socket 有没有发生变化。
(轮询)poll 提供了更优质的编程接口,但是本质和 select 模型相同。因此千级并发以下的 I/O,你可以考虑 select 和 poll,但是如果出现更大的并发量,就需要用 epoll 模型。
(事件驱动)epoll 模型在操作系统内核中提供了一个中间数据结构,这个中间数据结构会提供事件监听注册,以及快速判断消息关联到哪个线程的能力(红黑树实现)。因此在高并发 I/O 下,可以考虑 epoll 模型,它的速度更快,开销更小。
16.6、总结
在服务端有两种 Socket 文件,每个客户端接入之后会形成一个客户端的 Socket 文件,客户端 Socket 文件的文件描述符会存入服务端 Socket 文件。通过这种方式,一个线程可以通过读取服务端 Socket 文件中的内容拿到所有的客户端 Socket。这样一个线程就可以负责响应所有客户端的 I/O,这个技术称为 I/O 多路复用。
主动式的 I/O 多路复用,对负责 I/O 的线程压力过大,因此通常会设计一个高效的中间数据结构作为 I/O 事件的观察者,线程通过订阅 I/O 事件被动响应,这就是响应式模型。
以上内容为个人学习理解,如有问题,欢迎在评论区指出。
部分内容截取自网络,如有侵权,联系作者删除。