计算机网络学习笔记

五层协议体系结构

在这里插入图片描述

应用层

应用层的任务是通过应用进程间的交互来完成特定网络应用,它定义了信息交换的格式,比如 HTTP 协议中定义了报文头报文体,协议双方按这种规则来发送接受数据

这一层传输的东西叫应用层报文

如果是七层体系结构,应用层还有表示层和会话层。OSI 的七层体系结构概念清楚,理论也很完整,但是它比较复杂而且不实用,而且有些功能在多个层中重复出现。但是如此细致的分层可以让我们对网络的理解更进一步

比如在 OSI 分层的时候,会话层在第五层,用来给不同的应用建立与管理会话。表示层在第六层,用于数据的解密、加密、翻译以及压缩等操作。第七层就是应用层,每个安装在电脑上的软件在这一层发挥作用

拿 dubbo 服务调用来举例,dubbo 的 RPC 协议在第五层,对上层封装了服务调用的过程,作用就是将数据发送到另外一台机器上。dubbo 的各种序列化协议在第六层,用于处理数据的转换,转换后的数据提供给第七层使用

常用的协议有以下几种:

  • DNS:管理域名与 IP 地址映射关系的分布式数据库
  • HTTP 协议:超文本传输信息,为了提供一种发送接受 HTML 文件的方法
  • FTP 协议:文件传输协议,20端口用于传输数据,21端口用于传输控制信息

常见端口有以下几种:

  • HTTP:80、8080(阿帕奇)
  • HTTPS:443
  • MySQL:3306
  • FTP:20,21
  • DNS:53
  • Redis:6379
  • Nacos:8848

传输层

传输层的主要任务就是负责向两台终端设备进程之间的通信提供通用的数据传输服务,对上层数据进行封装切割等操作,以及保证数据传输的准确性

传输层的协议 TCP 或 UDP 加上端口就可以标识一个应用层协议,TCP/IP 协议中的端口范围是从 0~65535

传输层主要传输 TCP 报文和用户数据报,这一层的主要协议如下:

  • TCP 协议:传输控制协议
  • UDP 协议:用户数据协议
  • ARQ 协议:自动重传请求

网络层

网络层的任务是选择合适的路由,为分组交换网上的不同主机提供通信服务

在计算机网络中进行通信的两个计算机之间可能会经过很多个数据链路,也可能还要经过很多通信子网。网络层的任务就是选择合适的网间路由和交换结点,确保数据及时传送

这一层传输的东西叫 IP 数据报,因为这一层使用的协议叫 IP 协议,因此互联网的网络层也叫做网际层或 IP 层

  • IP:网际协议 :网际协议 IP 是 TCP/IP 协议中最重要的协议之一,也是网络层最重要的协议之一,IP 协议的作用包括寻址规约、定义数据包的格式等等,是网络层信息传输的主力协议
  • ARP 协议 :ARP 协议,全称地址解析协议(Address Resolution Protocol),它解决的是网络层地址和链路层地址之间的转换问题,因为一个 IP 数据报在物理上传输的过程中,总是需要知道下一跳(物理上的下一个目的地)该去往何处,但 IP 地址属于逻辑地址,而 MAC 地址才是物理地址。具体来说是 IP 地址转 MAC 地址的一些问题
  • NAT 网络地址转换协议 :NAT 协议(Network Address Translation)的应用场景如同它的名称——网络地址转换,应用于内部网到外部网的地址转换过程中。具体地说,在一个小的子网(局域网,LAN)内,各主机使用的是同一个 LAN 下的 IP 地址,但在该 LAN 以外,在广域网(WAN)中,需要一个统一的 IP 地址来标识该 LAN 在整个 Internet 上的位置

数据链路层

数据链路层的作用是将网络层交下来的 IP 数据报组装成帧,在两个相邻节点间的链路上传送帧。每一帧包括数据和必要的控制信息(如同步信息,地址信息,差错控制等)

这一层传输的东西叫帧,一般使用的是以太网协议,也可能使用IEEE802.3、IEEE802.4等协议

帧头包含同步信息,地址信息,差错检测等信息,这样可以知道帧从哪开始、进行差错处理、了解目的地址与源地址。这里的差错校验与网络层校验的不同是,这里哦只保证一段链路的数据传输的准确性,而网络层保证的则是两个节点的准确性

物理层

物理层的作用是实现相邻计算机节点之间比特流的透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异,从网络层的第一层开始,已经对上层屏蔽下层的东西了,这里做的是现实事件到网络世界的转换。如果是4层网络模型,会将数据链路层与物理层糅合在一起
在这里插入图片描述

这一层传输的东西叫比特,就是代表0或者1的电流

TCP协议

三大特点:面向链接,可靠,字节流,某一特点都能说个一章节

三次握手

1,客户端向服务器发送连接请求,即发送 SYN 报文,此时请求里包含 seq = x

开始,SYN 报文不能携带数据,需要消耗一个序列号。发送方进入 synsend(同步发送)状态

2,服务器接到请求后,向客户端返回响应,也是 SYN 报文,此时:

ACK = 1(表示是否允许链接),ack = x + 1(根据接受的请求动态算出来的,发送回去用于对客户端确定序列号),seq = y

SYN 报文不能携带数据,需要消耗一个序列号,接收端进入 synrcvd(同步接受)状态

3,客户端向服务器回复响应,此时:

ack = y + 1,ACK = 1,seq = x + 1

可以携带报文,不携带报文不消耗序列号,接收端进入连接状态

  • 为什么要回传 syn?

TCP 中只要是数据,即使是一个字节,即使如 SYN,也需要确认的,毕竟可以发送报文只代表了客户端可以正常发送,并没有证明发送端可以正常接受报文

  • 为什么最后还要发送一次确认/为什么不是两次握手/为什么服务器接受到连接请求后不直接建立连接

为了避免连接资源被浪费

1,为了确定服务器接受正常、发送正常,客户端发送正常、接受正常

2,以上的回答有点模糊,更准确的说法是如果服务器发送的 syn 报文丢失,接收端没有建立连接但是服务器建立了连接,连接资源会被浪费

3,如果发送端的第一次请求因为延迟收到了,但是此时接收端已经接受了第二次请求并且已经传输完数据然后关闭连接了,此时此前滞留的那一次请求连接,网络通畅了到达了服务器,此时连接资源会被浪费

SYN攻击是什么,如何解决

在短时间内伪造大量不存在的 IP 地址,并向 Server 不断地发送 SYN 包,Server 则回复确认包,并等待 Client 确认,由于源地址不存在,因此 Server 需要不断重发直至超时,这些伪造的 SYN 包将长时间占用未连接队列,导致正常的 SYN 请求因为队列满而被丢弃

怎么解决呢:

1,缩短半连接等待时间
2,短时间受到某 IP 的重复 SYN 则丢弃后续请求
3,通过半连接队列的后备设置来解决

半连接队列

半连接状态,指 TCP 状态为 SYN_RCVD 的状态。服务器处于 Listen 状态时收到客户端 SYN 报文时放入半连接队列中

当 SYN queue 满了,系统会根据内核参数 net.ipv4.tcp_syncookies 的值来处理请求,tcp_syncookies 是用来防止 SYN flood 攻击。

原理是在半连接队列满时,SYN cookies 并不丢弃 SYN 请求,而是将源目的 IP、源目的端口号、接收到的 client 端初始序列号以及其他一些安全数值等信息进行 hash 运算,并加密后得到 server 端的初始序列号,称之为 cookie。server 端在发送初始序列号为 cookie 的 SYN+ACK 包后,会将分配的连接请求块释放。如果接收到 client 端的 ACK 包,server 端将 client 端的 ACK 序列号减 1 得到的值,与上述要素 hash 运算得到的值比较,如果相等,直接完成三次握手,构建新的连接

全连接队列

全连接状态,指 TCP 状态为的状态 ESTABLISHED。TCP 的连接状态从服务器(SYN+ACK)响应客户端后,到客户端的 ACK 报文到达服务器之前,则一直保留在半连接状态中;当服务器接收到客户端的 ACK 报文后,该条目将从半连接队列移到全连接队列尾部,即 accept queue

当 Accept queue 满了以后,即使 client 端继续向 server 端发送 ACK 的包,也会不被响应,此时 ListenOverflows+1,系统会根据 net.ipv4.tcp_abort_on_overflow 参数的值来决定如何返回。值为 0 表示直接丢弃该 ACK,但不会将连接信息从 SYN queue 队列中移除。当系统丢弃了最后阶段的 ACK,系统会根据参数 net.ipv4.tcp_synack_retries 的设置重新向 client 端发送 SYN+ACK 包。而 client 端在收到多个 SYN+ACK 包,会认为之前的 ACK 丢包了,于是 client 端又重新向 server 端发送 ACK 包。当在 accept queue 有空闲的时候最终完成连接。如果 accept queue 始终满员,则最终 client 将收到 RST 包

四次挥手

1,某一方主动关闭方请求断开连接,即发送 FIN(seq = x) 标志的数据包

2,被动关闭方回发响应,此时数据包里包含

ack = x + 1,ACK = 1,seq = y

3,等待一段时间后,被动关闭方发送 FIN 报文

seq = z,ack = x + 1,ACK = 1

4,主动关闭方接受报文给出回应,并等待一段时间(俩倍的报文来回时间),断开连接

ack = y + 1,ACK = 1,seq = x + 1

5,被动关闭方接受报文,立即关闭连接

  • 为什么需要等待两个最长报文段寿命 2MSL 的时间

主要是为了接受被动方的全部数据

1,主动关闭方的最后一个报文丢失时,被动关闭方会再次发送 fin 报文

2,客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文

  • 为什么需要四次挥手,不是三次

和上面问题的理由类似,被动关闭方可能有一些数据没有发完,所以 FIN 报文与 ACK 报文需要分开

  • 服务端主动关闭连接会发生什么

如果服务端主动关闭连接,那么服务端就会先发送 fin,最后要有个 2MSL 的 TIME-WAIT。如果服务端在一段时间内主动关闭的连接比较多,则服务端会有大量的 TIME-WAIT 状态的连接要等 2MSL 时间。这导致大量端口不可用

解决思路很简单,就是让服务器能够快速回收和重用那些 TIME_WAIT 的端口资源

linux 下直接对 /etc/sysctl.conf 文件进行修改即可

KeepAlive

TCP 设有一个保活计时器,服务器每收到一次客户端的请求后,都会重新复位这个计时器,时长通常设置为2个小时,如果两个小时还没有收到客户端的任何数据,服务器就会发送探测报文段,每间隔75秒发送一次,如果一连发了10个探测报文仍然没响应,服务器就认为客户端出了问题,关闭连接

这种东西叫心跳校验机制,KeepAlive 并不是默认开启的,在 Linux 系统上没有一个全局的选项去开启 TCP 的 KeepAlive。需要开启 KeepAlive 的应用必须在 TCP 的 socket 中单独开启,默认接受时间为7200秒

有很多判断对方是否挂掉的方式都是基于 tcp 的这个校验机制,比如 http 的保活计时器、zk 集群中的心跳校验、redis 的哨兵模式等

TCP通信粘包问题

是什么

TCP 粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾;可能多个完整的包粘在了一起,也有可能大包中含有不完整的包(这种情况叫拆包)

这个问题出现的核心原因是 TCP 是字节流服务,TCP 不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的

消息在进入传输层(TCP)时会被切片为一个个数据包。这个数据包的长度是 MSS

可以把网络比喻为一个水管,是有一定的粗细的,这个粗细由网络接口层(数据链路层)提供给网络层,一般认为是的 MTU(1500bity)

UDP 不可能出现粘包问题,因为它不用窗口接受,每次只接受一个数据包,每个 UDP 段都是一条消息,应用程序必须以消息为单位提取数据,而 TCP 是套接字传输方式

原因

TCP 粘包发生的表面原因有两点:

1,发送方如果有连续几次发送的数据都很少,通常 TCP 会根据优化算法把这些数据合成一包后一次发送出去(现在已经不常用这个了)

2,接收方如果未及时清理缓冲区的数据,造成多个包同时接收

处理

解决粘包问题有很多方案,以下提出部分方案:

1,定长发送,发送端在发送数据时都以 LEN 为长度进行分包。这样接收方都以固定的 LEN 进行接收,如此一来发送和接收就能一一对应了。分包的时候不一定能完整的恰好分成多个完整的 LEN 的包,最后一个包一般都会小于 LEN,这时候最后一个包可以在不足的部分填充空白字节

2,头尾部标记,在每个要发送的数据包的尾部设置一个特殊的字节序列,此序列带有特殊含义,跟字符串的结束符标识”\0”一样的含义,用来标示这个数据包的末尾,接收方可对接收的数据进行分析,通过尾部序列确认数据包的边界

头部标记则是定义一个用户报头,在报头中注明每次发送的数据包大小。接收方每次接收时先以报头的 size 进行数据读取,这必然只能读到一个报头的数据,从报头中得到该数据包的数据大小,然后再按照此大小进行再次读取

3,加入消息长度信息

在收到头标志时,里面还可以带上消息长度,以此表明在这之后多少 byte 都是属于这个消息的。如果在这之后正好有符合长度的 byte,则取走,作为一个完整消息给应用层使用

你可能注意到 TCP 采用头部标记与消息长度混合使用的方式防止粘包,同时还有参数校验等辅助方法保证传输的可靠性

IP层会出现粘包吗

不会

IP 层的传输类似与 UDP 传输,每次都会接受一个被切片后的数据段,就算一个 UDP 报文被切成多个字段,经过不同的路由器传输到终点,目标机器还是一个一个接受的

TCP 如何确保数据有效传输

1,ARQ 协议:发完一个分组就停止发送,等待对方确认,如果不能及时收到一个确认,将重发这个报文段
2,拥塞控制:当网络拥塞时,减少数据的发送
3,流量控制: TCP 连接的每一方都有固定大小的缓冲空间,流量控制是对接收方的窗口进行大小控制
4,序列号:TCP 给发送的每一个包进行编号,并根据 ack 判断这个报文序号是否正确
5,效验和: TCP 将保持它首部和数据的检验和,如果效验和有错会直接丢掉

  • 流量控制

通过滑动窗口来实现,接收端的滑动窗口可发送控制信息调整发送端窗口大小

  • 拥塞控制

控制发送端拥塞窗口的大小,使网络中数据量合理,主要由四种算法来实现

1,慢开始:由小到大逐渐增大发送窗口,每次来回大小乘二,以指数增长
2,拥塞控制:缓慢增加,每次来回大小加一
3,快重传
4,快恢复:快速恢复丢失的数据包。如果接收机接收到一个不按顺序的数据段,它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认,它会假定确认件指出的数据段丢失了,并立即重传

注:发送窗口通常维持在流量控制与要塞控制窗口中较小的那一个

UDP

无连接,不可靠,基于数据报文段

这里重点说一下数据报文段,基于数据报是指无论应用层交给 UDP 多长的报文,UDP 都照样发送,即一次发送一个报文。至于如果数据包太长,需要分片,那也是 IP 层的事情,大不了效率低一些。UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界

ARQ 协议(自动重传请求)

用于传输层与数据链路层,它通过使用确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输

停止等待 ARQ

传出一个数据,等待,接受回应后,继续传输
如果没有回应,重新发送
接收端收到相同数据,丢弃数据,发送回应
发送端收到相同回应,丢弃数据

连续 ARQ

发送端:维持一个滑动窗口,发送窗口里的所有数据
接收端:发送最后一个收到连续数据的回应

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值