网络是怎么连接笔记(二)用电信号传输TCP/IP数据

news2025/7/19 15:49:04

文章目录

  • 介绍
  • 创建套接字
  • 连接服务器
  • 收发数据
  • 从服务器断开并删除套接字
  • IP与以太网的包收发操作(待更新)
  • UDP协议的收发操作(待更新)

介绍

在了解了HTTP请求是如何产生的,以及网址是如何跳转到我们想要看到的页面,我们需要了解协议栈内部的细节
在这里插入图片描述

创建套接字

  • 我们将探索操作系统中的网络控制软件(协议栈)和网络硬件(网卡)是如何将浏览器的消息发送给服务器的?
  • 首先跟浏览器不一样的是,协议栈是操作系统内部的东西,所以我们用户是完全体验不到的,所以难以想象他是怎么工作的,所以下图介绍
    在这里插入图片描述
    • 整体的流程大概是这样的
      • 上面的部分是网络应用程序,也就是浏览器、电子邮件客户端、Web服务器、电子邮件服务器等程序,它们会将收发数据等工作委派给下层的部分来完成。
      • 应用程序的下面是 Socket 库,其中包括解析器,解析器用来向 DNS 服务器发出查询
      • 再下面就是操作系统内部了,其中包括协议栈。协议栈的上半部分有两块,分别是负责用 TCP 协议收发数据的部分和负责用 UDP 协议收发数据的部分,它们会接受应用程序的委托执行收发数据的操作。
      • 下面一半是用 IP 协议控制网络包收发操作的部分。在互联网上传送数据时,数据会被切分成一个一个的网络包 ,而将网络包发送给通信对象的操作就是由 IP 来负责的。此外,IP 中还包括 ICMP 协议和 ARP 协议。 ICMP 用于告知网络包传送过程中产生的错误以及各种控制消息,ARP 用于根据 IP 地址查询相应的以太网 MAC 地址 。
      • IP 下面的网卡驱动程序负责控制网卡硬件,而最下面的网卡则负责完成实际的收发操作,也就是对网线中的信号执行发送和接收的操作。
  • 我们已经具体了解了协议栈是怎么个工作方式,下面了解一下套接字的详细信息
    • 协议栈内部存放一块用户控制信息的内存空间,这里用于记录通信操作的一些控制信息,主要为下面几个部分:
      • 协议类型
      • IP地址和端口号
      • 通信对象的IP地址和端口号
      • 通信状态
      • 套接字的标识符
        在这里插入图片描述
  • 了解了套接字的具体样子以后,我们需要看看客户端调用Socket组件,协议栈是如何工作的?
    在这里插入图片描述

连接服务器

  • 创建完套接字之后,就会调用connet,然后协议栈就会通过本地的套接字跟远端的套接字进行连接,连接实际上是通信双方交换控制信息,在套接字中记录这些必要信息并准备数据收发的一连串操作
  • 连接操作的目的:套接字刚刚创建完成的时候,里面并没有存放任何数据,也不知道通信的对象是谁。在这个状态下,即便应用程序要求发送数据,协议栈也不知道数据应该发送给谁。浏览器可以根据网址来查询服务器的 IP 地址,而且根据规则也知道应该使用 80 号端口,但只有浏览器知道这些必要的信息是不够的,因为在调用 socket创建套接字时,这些信息并没有传递给协议栈。因此,我们需要把服务器的 IP 地址和端口号等信息告知协议栈
  • 当执行数据收发操作时,我们还需要一块用来临时存放要收发的数据的内存空间,这块内存空间称为缓冲区
  • 控制信息分为两类:
    • 一类 头部中记录的信息 :是客户端和服务器相互联络时交换的控制信息,这些信息不仅连接时需要,包括数据收发和断开连接操作在内,整个通信过程中都需要,这些内容在 TCP 协议的规格中进行了定义
      在这里插入图片描述
      在这里插入图片描述
    • 另一类 套接字(协议栈中的内存空间)中记录的信息 :是保存在套接字中,用来控制协议栈操作的信息,应用程序传递来的信息以及从通信对象接收到的信息都会保存在这里,还有收发数据操作的执行状态等信息也会保存在这里,协议栈会根据这些信息来执行每一步的操作
  • 连接的实际过程:
    • 将服务器IP和端口号,传给 客户端协议栈 的TCP模块
    • 客户端TCP模块 创建头部信息,然后传给 客户端IP模块
    • 客户端IP模块 执行网络包(控制位SYN设置为1)进行发送
    • 服务器IP模块 接收到网络包,并将数据传输给 服务器TCP模块
    • 服务器TCP模块 从头部信息找到对应的端口号,并根据端口号找到对应的套接字,修改套接字的状态
    • 服务端TC模块 返回响应(控制位SYN设置为1和ACK设置为1)给 服务端IP模块,并委托进行发送
    • 客户端IP模块 收到响应,并把数据传输到 客户端TCP模块
    • 客户端TCP模块确认信息,是否连接成功
    • 如果连接成功(SYN设置为1),客户端IP模块 会向套接字输入对应服务器的IP地址等信息,还将状态改为连接状态
    • 客户端IP模块 返回响应(ACK设置为1)给服务端IP模块
    • 服务端IP模块收到响应
    • 数据传输

收发数据

  • 控制流程从connect 回到应用程序之后,接下来就进入数据收发阶段。
  • 协议栈收到数据,发送数据
    • 协议栈不关系应用程序传来的数据是什么内容,应用程序在调用write时会指定发送数据的长度
    • 协议栈并不是已收到数据就马上发送出去,会将数据存放到内部的发送缓冲区中,并等待应用程序的下一段数据,达到一定的数据量才会发送数据
      • 如何界定需要多少数据量才会发送呢?
        • 其中一个要素:每个网络包能容纳的数据长度,协议栈会根据一个叫做MTU的参数来进行判断,MTU表示一个网络包的最大长度在以太网中一般是 1500 字节 。MTU 是包含头部的总长度,因此需要从 MTU 减去头部的长度,然后得到的长度就是一个网络包中所能容纳的最大数据长度,这一长度叫作MSS 。当从应用程序收到的数据长度超过或者接近 MSS 时再发送出去,就可以避免发送大量小包的问题了。
          在这里插入图片描述
        • 另一个要素:时间,当应用程序发送数据的频率不高的时候,如果每次都等到长度接近 MSS 时再发送,可能会因为等待时间太长而造成发送延迟,这种情况下,即便缓冲区中的数据长度没有达到 MSS,也应该果断发送出去。为此,协议栈的内部有一个计时器,当经过一定时间之后,就会把网络包发送出去 32。
      • HTTP 请求消息一般不会很长,一个网络包就能装得下,但如果其中要提交表单数据,长度就可能超过一个网络包所能容纳的数据量,比如在博客或者论坛上发表一篇长文就属于这种情况。如何解决?
        • 这个时候就需要对数据进行拆分,拆分出来的每块数据会被放进单独的网络包中
          在这里插入图片描述
  • 现在协议栈已经装好数据准备发往服务器了,但是发送数据,还需要确认对方有没有收到数据,并且收到数据有没有正确,不然的话就没有意义了,所以收发数据还有一个很重要的操作,就是 确认操作。
    • TCP模块 再拆分数据时,会算好每一块数据在第几个字节,并且会在发送的时候将第几个字节卸载TCP头部发送出去,这就是序号这个字段的作用,并且这个数据的长度也会告知对方,所以接收方可以通过这个来判断数据是否异常和组装数据。
      • 假设上次接收到第 1460 字节,那么接下来如果收到序号为 1461 的包,说明中间没有遗漏;但如果收到的包序号为 2921,那就说明中间有包遗漏了。
    • 接收方收到数据后,还需要计算收到了多少字节的数据,并且将这个数据放进TCP头部的ACK发送给发送方。
      • 发送方说的是“现在发送的是从第 ×× 字节开始的部分,一共有 ×× 字节哦!”而接收方则回复说,“到第 ×× 字节之前的数据我已经都收到了哦!”这个返回 ACK 号的操作被称为确认响应,通过这样的方式,发送方就能够确认对方到底收到了多少数据。
    • ps:在实际的通信中,序号并不是从 1 开始的,而是需要用随机数计算出一个初始值,这是因为如果序号都从 1 开始,通信过程就会非常容易预测,有人会利用这一点来发动攻击。但是如果初始值是随机的,那么对方就搞不清楚序号到底是从多少开始计算的,因此需要在开始收发数据之前将初始值告知通信对象。
      在这里插入图片描述
    • 之前都只是单向传输,但实际上服务端跟客户端应该是双向传输,不仅是服务端会发送数据,客户端也会发送数据过来。双方都需要计算ACK号和序号
      • 例子:首先客户端先计算出一个序号,然后将序号和数据一起发送给服务器,服务器收到之后会计算 ACK 号并返回给客户端;相反地,服务器也需要先计算出另一个序号,然后将序号和数据一起发送给客户端,客户端收到之后计算 ACK 号并返回给服务器。此外,如图所示,客户端和服务器双方都需要各自计算序号,因此双方需要在连接过程中互相告知自己计算的序号初始值。
        在这里插入图片描述
      • 具体流程:
        • 客户端在连接时需要计算出与从客户端到服务器方向通信相关的序号初始值,并将这个值发送给服务器
        • 服务器会通过这个初始值计算出 ACK 号并返回给客户端。初始值有可能在通信过程中丢失,因此当服务器收到初始值后需要返回 ACK 号作为确认。
        • 服务器也需要计算出与从服务器到客户端方向通信相关的序号初始值,并将这个值发送给客户端。
        • 接下来像刚才一样,客户端也需要根据服务器发来的初始值计算出 ACK 号并返回给服务器。
        • 到这里,序号和 ACK 号都已经准备完成了,接下来就可以进入数据收发阶段了。数据收发操作本身是可以双向同时进行的,但 Web 中是先由客户端向服务器发送请求,序号也会跟随数据一起发送。
        • 然后,服务器收到数据后再返回 ACK 号。从服务器向客户端发送数据的过程则正好相反。
          在这里插入图片描述
  • 实际情况下,还会出现很多问题,所以网络的错误检测和补偿机制还有几点:
    • 首先是返回 ACK 号的等待时间(这个等待时间叫超时时间)当网络传输繁忙时就会发生拥塞,ACK 号的返回会变慢,这时我们就必须将等待时间设置得稍微长一点,否则可能会发生已经重传了包之后,前面的 ACK 号才姗姗来迟的情况。
      • 所以将等待时间设置为一个固定值并不是一个好办法。因此,TCP 采用了动态调整等待时间的方法,这个等待时间是根据 ACK 号返回所需的时间来判断的。具体来说,TCP 会在发送数据的过程中持续测量 ACK 号的返回时间,如果 ACK 号返回变慢,则相应延长等待时间;相对地,如果 ACK 号马上就能返回,则相应缩短等待时间
      • 每发送一个包就等待一个 ACK 号的方式是最简单也最容易理解的,但在等待 ACK 号的这段时间中,如果什么都不做那实在太浪费了。所以产生了滑动窗口,就是发送一个包之后,不等待ACK号返回,而是直接发送后续的一系列包
        在这里插入图片描述
        • 先说这个操作的问题,当接收方的 TCP 收到包后,会先将数据存放到接收缓冲区中。然后,接收方需要计算 ACK 号,将数据块组装起来还原成原本的数据并传递给应用程序,如果这些操作还没完成下一个包就到了也不用担心,因为下一个包也会被暂存在接收缓冲区中。如果数据到达的速率比处理这些数据并传递给应用程序的速率还要快,那么接收缓冲区中的数据就会越堆越多,最后就会溢出。缓冲区溢出之后,后面的数据就进不来了,因此接收方就收不到后面的包了,这就和中途出错的结果是一样的,也就意味着超出了接收方处理能力。
        • 知道问题所在之后,我们就需要措施去避免,首先,接收方需要告诉发送方自己最多能接收多少数据,然后发送方根据这个值对数据发送操作进行控制,这就是滑动窗口方式的基本思路。
          在这里插入图片描述
    • 知道了滑动窗口之后,还有一个问题,那就是返回 ACK 号和更新窗口的时机。如果假定这两个参数是相互独立的,分别用两个单独的包来发送,结果会如何呢?
      • 其实没必要每次都向发送方更新窗口大小,因为只要发送方在每次发送数据时减掉已发送的数据长度就可以自行计算出当前窗口的剩余长度。因此,更新窗口大小的时机应该是接收方从缓冲区中取出数据传递给应用程序的时候。这个操作是接收方应用程序发出请求时才会进行的,而发送方不知道什么时候会进行这样的操作,因此当接收方将数据传递给应用程序,导致接收缓冲区剩余容量增加时,就需要告知发送方,这就是更新窗口大小的时机。
      • 那么 ACK 号又是什么情况呢?当接收方收到数据时,如果确认内容没有问题,就应该向发送方返回 ACK号,因此我们可以认为收到数据之后马上就应该进行这一操作。
  • 发送 HTTP 请求消息后,接下来还需要等待 Web 服务器返回响应消息。对于响应消息,浏览器需要进行接收操作,这一操作也需要协议栈的参与。

从服务器断开并删除套接字

  • 当数据的收发接近尾声,协议栈也需要一些收尾操作。,收发数据结束的时间点应该是应用程序判断所有数据都已经发送完毕的时候。这时,数据发送完毕的一方会发起断开过程,但不同的应用程序会选择不同的断开时机。
    • 例子:服务端一方发起断开过程为例子
      • 服务器会调用Socket库中的close程序,服务器协议栈会生成包含断开信息TCP头部信息,然后将FIN置为1
      • 服务器协议栈会委托IP模块给客户端发送数据
      • 客户端收到FIN为1 的 TCP头部后,客户端会将自己的套接字置为断开的状态,然后为了告诉服务器也发送了一个FIN为1的TCP头部
      • 服务器接收到客户端的FIN为1 的 TCP头部,也返回一个ACK号
      • 客户端收到后,就开始通知应用程序来读数据了,调用 close 来结束数据收发操作
        在这里插入图片描述
  • 和服务器的通信结束之后,用来通信的套接字也就不会再使用了,这时我们就可以删除这个套接字了。不过,套接字并不会立即被删除,而是会等待一段时间之后再被删除。
    • 原因是因为如果最后客户端返回的 ACK 号丢失了,结果会如何呢?这时,服务器没有接收到 ACK 号,可能会重发一次 FIN。如果这时客户端的套接字已经删除了,会发生什么事呢?套接字被删除,那么套接字中保存的控制信息也就跟着消失了,套接字对应的端口号就会被释放出来。这时,如果别的应用程序要创建套接字,新套接字碰巧又被分配了同一个端口号 ,而服务器重发的 FIN 正好到达,会怎么样呢?本来这个 FIN 是要发给刚刚删除的那个套接字的,但新套接字具有相同的端口号,于是这个 FIN 就会错误地跑到新套接字里面,新套接字就开始执行断开操作了。之所以不马上删除套接字,就是为了防止这样的误操作。

IP与以太网的包收发操作(待更新)

UDP协议的收发操作(待更新)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/395571.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

普元ESO 逻辑流/页面流数据类型选择java--浏览转圈卡死

不知道什么时候开始的 前阵子在选择数据类型需要选择一个普元基本类型里没有的java类型的时候 它卡住了,虽然我对lj普元的容忍度较高,但是在等了五分钟以后还在那转我就忍不了了 在经历了重启eos 重启电脑 关闭所有软件运行eos后,最后忘了咋折腾的反正是整上这个类型了当时确…

Unity使用NatML的NatDevice功能调用外部摄像机

Unity使用NatML的NatDevice功能调用外部摄像机NatCamNatDevice广泛和轻量级在Unity中使用NatDevice导入NatDevice指定访问密钥运行摄像头预览示例测试结果NatCam 最开始在Unity中使用WebCamTexture获取外部摄像机的画面。后来发现WebCamTexture的功能过于简单,外部…

拥塞管理与拥塞避免

拥塞管理与拥塞避免背景来源产生情景队列技术FIFO:First In First OutRR:Round RobinWRR:Weight Round RobinPQ(Priority Queuing)CQ(Custom Queuing)WFQ(Weight Fair Queuing&#…

入托不焦虑 | 如何帮宝宝更好地融入托班?

上托班是教育重要的一环,是宝宝开始适应集体过程的起点,宝爸宝妈也是忧喜交加:高兴的是宝宝慢慢长大开始上学了;忧虑的是从没有离开家的宝宝会不会适应托班生活呢? 今天我们就来分享一下如何引导宝宝更快地适应园区生…

【Unity】程序集Assembly模块化开发

笔者按:使用Unity版本为2021.3LTS,与其他版本或有异同。请仅做参考 一、简述。 本文是笔者在学习使用Unity引擎的过程中,产学研的一个笔记。由笔者根据官方文档Unity User Manual 2021.3 (LTS)/脚本/Unity 架构/脚本编译/程序集定义相关部分结…

【Spring6】IoC容器之基于注解管理Bean

3.3、基于注解管理Bean(☆) 从 Java 5 开始,Java 增加了对注解(Annotation)的支持,它是代码中的一种特殊标记,可以在编译、类加载和运行时被读取,执行相应的处理。开发人员可以通过…

Java基本数据类型变量自动提升、强制类型转换、String基本类型使用

文章目录基本数据类型变量自动提升特殊情况强制类型转换String基本类型使用基本数据类型变量自动提升 规则: 将取值范围小(或容量小)的类型自动提升为取值范围大(或容量大)的类型 。 byte、short、char-->int-->…

HCIP---回顾HCIA

HCIA回顾: 抽象语言---编码 编码---二进制 二进制---电信号 处理电信号 OSI参考模型----OSI/RM (Open System Interconnect-----开放式系统互连) 应用层:为终端用户提供网络服务接口 表示层:提供数据格式转换服务 会话层&#xff1a…

基于深度学习的鸟类检测识别系统(含UI界面,Python代码)

摘要:鸟类识别是深度学习和机器视觉领域的一个热门应用,本文详细介绍基于YOLOv5的鸟类检测识别系统,在介绍算法原理的同时,给出Python的实现代码以及PyQt的UI界面。在界面中可以选择各种鸟类图片、视频以及开启摄像头进行检测识别…

基于同步整流技术的Buck开关电源设计方法

基于同步整流技术的Buck开关电源设计方法 典型的Buck电路 同步整流的Buck电路 摘要 B u c k 变换器作为一种基本的开关电源变换器,在电力变换场合具有广泛的应用。 为解决 B u c k 变换器工作在电感电流连续状态下,续流二极管关断时存在较大的反向电流…

重资产模式和物流网络将推动京东第四季度利润率增长

来源:猛兽财经 作者:猛兽财经 强劲的2022年第三季度财务业绩 2022年11月18日,京东(JD)公布了2022年第三季度财务业绩,净收入为2435亿元人民币,增长了11.4%。净服务收入为465亿元人民币&#xf…

【C++知识点】异常处理

✍个人博客:https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 📚专栏地址:C/C知识点 📣专栏定位:整理一下 C 相关的知识点,供大家学习参考~ ❤️如果有收获的话,欢迎点赞👍…

深度学习知识点全面总结_深度学习总结

深度学习知识点全面总结_深度学习总结 神经网络与深度学习结构(图片选自《神经网络与深度学习》一邱锡鹏) 目录 常见的分类算法 一、深度学习概念 1.深度学习定义 2.深度学习应用 3.深度学习主要术语 二、神经网络基础 1. 神经网络组成 感知机 多层感知机 3.前向传播…

【JS代码优化二】ES6 数组和对象篇

Vue3 Vite VueRouter Pinia Axios Element Plus 项目实战(持续更新中…) 序:如何让代码看起来更优雅?代码是由文字堆叠起来的可以被机器执行的程序。它记载着相关信息(状态)、表达相关的情绪&#xf…

vue中引入路径用法及说明

引入路径的用法及说明Vue文件中引用路径的介绍1、路径 ././当前文件同级目录2、路径 …/…/当前文件上一级目录3、符号 的作用是在你引入模块时,可以使用 代替 /src 目录,避免易错的相对路径。Vue中使用1. vue.config.js配置文件中使用chainWebpack(con…

Go语言学习的第三天--上部分(基础用法)

前两天经过不断度娘,与对up主的跟踪学习了解了go的历史,今天开始了go的基础!!本章主要是go 的注释、变量及常量的梳理一、注释不管什么语言都有自己的注释,go也不例外 !!单行注释 // 多行注释 …

22- Pytorch实现天气分类 (Pytorch系列) (项目二十二)

项目要点 4种天气数据的分类: cloudy, rain, shine, sunrise.all_img_path glob.glob(rG:\01-project\08-深度学习\day 56 迁移学习\dataset/*.jpg) # 指定文件夹 # import glob获取随机数列: index np.random.permutation(len(all_img_path))建立数组和索引的关…

Java操作数据库基本原理

- 四年前存稿 Java操作数据库基本原理概述 全称Java Database Connectivity,Java的数据库连接,使用Java语言操作数据库,定义了操作所有关系型数据库规则(接口) 使用步骤 我的mysql是8版本的,使用jar包时必须使用8版本的&#x…

6年Android开发最终被优,事后加入车载开发,开启新起点~

如今传统Android 开发行业的岗位越发紧张了,经过去年一些互联网大厂的部门人员优化、开源截流等操作,加快了内卷的速度,原本坐山观虎斗我,没想到也被卷入其中。 1. Android 开发6年,无情中招 就去年年底,…

RZ/G2UL核心板-40℃低温启动测试

1. 测试对象HD-G2UL-EVM基于HD-G2UL-CORE工业级核心板设计,一路千兆网口、一路CAN-bus、 3路TTL UART、LCD、WiFi、CSI 摄像头接口等,接口丰富,适用于工业现场应用需求,亦方便用户评估核心板及CPU的性能。HD-G2UL-CORE系列工业级核…