《网络是怎样连接的》阅读笔记

在这里插入图片描述

Chapter1: 浏览器生成消息

  • 为什么要用域名代替IP地址访问?
    • 域名比IP地址更好记
    • 如果服务器使用了虚拟主机功能,则无法通过IP地址访问
  • 为什么要用DNS把域名转换为IP地址,直接使用域名确定通信对象不行吗?
    • IP地址长度为32bit(4字节),而域名需要几十个字节,增加了路由器负担,传送时间也会变长
    • 而且IP长度固定,域名长度不固定,处理更复杂
    • 域名不像IP地址那样有区域性和层次性
  • Socket库解析IP地址的步骤
    • 调用了gethostbyname函数
      在这里插入图片描述
  • IP地址由网络号与主机号组成,通过子网掩码分割
    • 二者边界不是一定在句号上的
      在这里插入图片描述

Chapter2: 用电信号传输TCP/IP数据

协议栈

  • 操作系统中控制网络通信的部分称为协议栈
    • 一般包括上层TCP,UDP协议模块和下层IP协议模块
    • 应用程序(例如浏览器)委托它传递信息
    • 套接字就是协议栈中存放控制信息(地址,端口等)的内存空间
      • 套接字本身只是一个抽象概念
  • Socket连接过程
    • 开辟一块内存放置套接字结构体,并写入初始信息
      • 例如要使用IPv4,tcp连接
    • 客户端把要通信的服务器IP和端口写入套接字,向服务器发送连接信息
    • 服务器等待连接,当数据包到来时,解析出TCP头部中的端口号,找到对应的套接字,写入客户端信息(地址,端口)并修改状态为正在连接
  • 缓冲区
    • socket在初始化时会开辟一块缓冲区临时存放要收发的数据
      • 协议栈并不是一收到应用程序发来的数据就发送网络包的,这样会产生大量小包,而是累计一定数据后才发送
    • 所以对于上层应用程序来说,调用了send向协议栈(具体来说是某一套接字)发送数据后就直接返回了,send的任务仅仅是把数据拷贝到协议栈缓冲区中,发送给目标套接字是TCP的任务

在这里插入图片描述

  • 协议栈判断发送时机的依据
    • 等待收到的数据超过或接近网络包所能容纳的最大数据长度后(MSS)才发送
      • 网络包(MTU)最大大小取决于传输过程中经过网络的类型,如以太网,无线网等
    • 协议栈内置超时
      • 防止应用程序发送数据频率太小,为了等待数据接近最大数据长度而造成的延迟

在这里插入图片描述

  • TCP与IP的分片
    • 上面的操作实际上的TCP协议主动帮IP协议做的分片操作
    • 实际上TCP是可以不分片的,例如UDP就不会分片,而是由IP分片
  • 为什么TCP要多此一举呢?
    • 因为如果交给IP分片,那么如果其中一个分片丢失,由于IP协议没有错误补偿功能,导致TCP发送失败,这样TCP就需要再次发送整个大数据
    • 如果TCP先分片了,就只要重传一个分片的数据
    • 而UDP本身没有重传机制,所以无所谓丢失一个分片还是整个数据

参考:https://blog.csdn.net/ns_code/article/details/30109789

TCP通信过程

  • 使用ACK号确认网络包已经收到

    • 发送方在发送数据包的时候,会在TCP头部写入数据的序号
      • 及数据是从头开始的第几个字节
      • 为了通信安全,序号不从1开始,而是随机计算一个初始值
    • 接收方把数据包长度减去头部长度得到数据长度,并和序号相加,写入TCP头部的ACK字段,返回给发送方
      • 并且要设置控制位的ACK比特为一,表示ACK数据有效
    • 在收到接收方的ACK号并确认无误前,发送方把发送的数据暂存在缓冲区中,以便重传
    • 其实可以不用每次接受都发送一个ACK号,而是几次接收后返回最后一个号
  • 因为TCP 协议拥有错误补偿机制,因此网卡,路由器,集线器等都不再有错误补偿机制,而是发生错误直接丢包

  • SYN控制位置1表示连接开始,此时序号为随机的初始值

  • 动态等待ACK返回的时间

    • 发送方在长时间收不到ACK返回时重传数据
    • 但是返回时间收到网络状况影响,可能会产生不必要的重传,增加网络负担
    • 因此发送方会监测ACK返回时间并动态调整超时时间
  • 滑动窗口

    • 初始的TCP,发送方在等待ACK返回再发送下一个包
    • 为了提高效率,可以一次性发送多个包,接收方应用程序处理前把包存在缓冲区中
    • 为了防止发送速率大于处理速率时产生缓冲区溢出,接收方需要告知发送方缓冲区还有多少空间,发送方据此调整发送速率
    • 该窗口更新的信息的包可以和ACK包合并为一个包
  • TCP断开连接过程

    • 允许服务器(HTTP1.0)和客户端(HTTP1.1)任意一端主动断开连接
    • A发起断开连接,把TCP头部FIN位设置为1
    • B返回ACK号表示收到断开信息
    • 当B端应用程序向号协议栈求数据时(read),协议栈告知数据传输完毕,此时应用程序调用close结束连接,B也发送FIN为1的数据包
    • A返回ACK表示收到B发送的断开信息
    • 在TCP断开后,A中的套接字还会存在一段时间
      • 因为如果A最后返回的ACK丢失了,B会再次发送FIN
      • 如果此时旧的套接字已经删除,恰巧同一个端口绑定了新套接字,这个套接字会被错误地关闭

路由器和交换机

  • 路由器是按照IP协议判断下一个路由器位置的设备
    • 使用IP地址查找IP表来判断
    • 路由器会在接受包后丢弃老的MAC地址,然后根据IP地址添加新的MAC地址
  • 交换机是在子网中按照以太网协议把包传输到下一个路由器的设备
    • 使用MAC地址查找MAC表来判断
    • 上述描述是建立在以太网的基础上的,实际上还可能是无限局域网等别的网络,它们有各自的协议,但是功能是一样的
      在这里插入图片描述

IP模块与包的收发

  • IP模块负责添加IP头部和MAC头部,然后传递给网卡发送出去

    • 注意MAC头部也是由TCP/IP协议栈软件添加的,而不是网卡
  • IP头部

    • 包含了IP消息长度,发送方和接受方IP地址,上层协议号等信息
      • 例如TCP,UDP协议
  • MAC头部

    • 包含了接收方和发送方MAC地址,以及以太协议类型
      • 例如IP协议,ARP协议
    • 接收方MAC地址是通过IP地址使用ARP广播的方式得到的
      • 因此接收方和发送方必须在同一子网中
  • IP分片后,中间路由器是不会重组的,只有到目标主机处才重组

    • 因为无法保证一个数据包分片后每个小包结果的路径是一样的
    • 路由重组后还会再被分片
      在这里插入图片描述
  • 发送方网卡负责从IP模块获取包,并把包转换为电信号

    • MAC模块添加报头以方便接收方的MAC模块察觉到包
    • 在末尾添加FCS校验,接收方根据包的内容计算出FCS并与发送方的FCS比较,判断包是否损坏

在这里插入图片描述

  • 由于TCP/UDP头部没有记录IP地址,所以接收方的TCP/UDP模块需要查看IP头部以确定应该把数据发送给哪个套接字

Chapter3: 从网线到网络设备

  • 前两章的内容都是发生在计算机内部的,下面的内容展现了网络包在离开计算机后的传输过程
  • 在子网中,计算机设备通过交换机连接,并由路由器负责连接外网
    • 家用路由器集成了交换机
      在这里插入图片描述

交换机

  • 交换机和网卡的区别在与交换机没有MAC地址
    • 如果让网卡接受所有网路包并通过软件转发,那么这台计算机就成了一个交换机
      在这里插入图片描述
  • 当设备通过交换机发送过数据时,该设备MAC号自动加入交换机MAC表
    • 因为设备可能会移动,所以MAC表需要定期删除

在这里插入图片描述

路由器

  • 路由器由转发模块(相当于IP模块)和端口模块(相当于网卡)组成
    • 路由器的各个端口都有有自己的MAC地址和IP地址
      在这里插入图片描述
  • 路由表只匹配网络号,忽略主机号
    • 即路由表目标地址一栏表示的是子网
    • 交换机需要MAC地址完全一致才转发,而路由器只要匹配网络号即可
      • 当然也可以匹配所有地址,此时该行表示一台计算机
    • 有时路由表中的子网掩码和地址本事的子网掩码不同,这是路由聚合的结果
      在这里插入图片描述
  • 路由表中的interface表示端口IP地址,Gateway表示要转发到的IP地址
    • 如果网关地址和端口地址相同,或者网关地址为空,则表示下一个地址即为目标地址,直接转发到IP头部的IP地址
  • 第一行0.0.0.0为默认路由,所有地址都能匹配到这一行
    在这里插入图片描述

Chapter4: 通过接入网进入互联网内部

  • 光纤比电缆快的原因是什么?
    • 光信号和电信号的传播速度是一样的
    • 但是电信号在提高通信速率的同时衰减率会提高,会导致信号无法传到目的地
    • 而光信号衰减率很低,可以尽量提高通信速率

Chapter5: 服务端的局域网中有什么玄机

防火墙

  • 防火墙不会检查通信数据的内容,也就无法地域藏在通信数据中的攻击

  • 防火墙的包过滤规则举例

    • 行1允许外网访问指定服务器
    • 行2禁止服务器主动访问外网
      • 由于UDP不像TCP有建立连接的过程,因此无法只限制内网主动访问外网
      • 所以一般的服务器禁止UDP流量,只允许访问外网DNS服务器的UDP流量
    • 行3允许服务器应答外网
    • 端口号限制服务器上的指定服务(如WEB服务)与外网通信
    • 由于现在的防火墙也充当了连接外网的路由器,具有地址转换功能,因此无须设置禁止外网访问内网的规则

在这里插入图片描述

内容分发网络(CDN)

  • 位于服务端的缓存服务器无法减少网络上的流量,也无法降低客户端延迟
  • 位于客户端的缓存服务器不受服务端控制,对于新的数据无法缓存
  • 可以把缓存服务器放在里客户端近的网络运营商处,这被称为CDN
  • 现在的问题就在于如何找到离客户端最近的缓存服务器
    • 方法一
      • 客户端的本地DNS查找位于服务端的权威DNS服务器
      • 权威DNS服务器根据本地DNS的IP地址确定其位置,并计算和所有缓存服务器距离
      • 最后返回最近的缓存服务器的IP地址
      • 这种方法的缺点在于客户端DNS和客户端不一定在一起
    • 方法二
      • 服务端DNS直接返回重定向服务器地址,客户端访问重定向服务器
      • 重定向服务器直接根据客户端IP地址计算距离,返回缓存服务器IP地址
      • 这种方法的优点在于客户位置精确,缺点在于多了一次请求过程
    • 方法三
      • 基于方法二,只不过服务端返回计算距离的脚本,由客户端计算最近缓存服务器

Chapter6: 请求到达Web服务器,响应返回浏览器

  • web服务器一般通过80端口通信,也就是一个端口对应了很多套接字
    • 所以为了确认客户端连接到了哪个套接字,需要通过服务器和客户端的IP和端口四元组确定
  • 既然如此,为了还要通过描述符指代套接字呢,直接用四元组不就好了?
    • 在套接字刚创立时,四元组信息还不全
    • 描述符只有一种信息,更简洁

服务器接受包的过程

  • 网卡
    • 网卡监测、处理所有经过的包并校验,然后根据MAC头部决定接受不接受
      • 此时CPU无感知,执行其他任务
    • 接受后放入网卡缓冲区,并发出中断信号,让CPU根据MAC头部协议号交给对应的协议栈处理
  • IP模块
    • 检查目标IP地址是否为自己
      • 如果不是,普通服务器直接丢弃,路由器进行转发
    • 检查是否分片,组装还原成原始包
    • 检查头部协议号,交给上层处理
  • TCP模块
    • 对于连接包(STN位为1)
      • 检查接收方端口号
      • 把客户端IP,端口,序号初始值,窗口大小等写入对应套接字
        • 这样套接字就保存了所有的通信状态
      • 发送ACK号
    • 对于数据包
      • 找到对应套接字,检查序号
      • 读取数据到缓冲区并拼接,等待应用程序读取
      • 发送ACK号(可能会和后续应答包合并发送)
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值