IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 数据在网络中如何传输的 -> 正文阅读

[网络协议]数据在网络中如何传输的

大家好,我是小蛋。

数据传输的整个过程总结为四个词就是创建、连接、发送、断开。每个交互过程都会进行详细说明,耐心往下看哦。

交互过程如下图所示:

image-20211202222727911

套接字如何创建的

协议栈内部结构

image-20211202214742571

如上图所示,整个请求交互过程分为了几个部分,首先最上层就是应用程序,接着往下是 Socket 库。

再下面就是操作系统的内部了,这里面就包括了协议栈,协议栈上半部分为 TCP 和 UDP ,它们都是负责数据的收发,只是一个需要 连接,一个不需要连接可以直接收发数据,这两者的详细区别我会在后期文章单独讲解,这里大家先了解下就行。

协议栈的下半部分是 IP 协议,用来真正将数据转变为网络包进行实际数据传送的媒介。

IP 下面就是网卡驱动程序,用来控制网卡硬件。

认识套接字

在协议栈内部有一块用来存放控制信息的内存空间,这里面记录了需要连接的对象 IP 地址、端口号、进行状态等信息。

而套接字本身其实只是一个概念,实际并没有这样一个东西,这个概念如果非要赋予它一个实体,那控制信息可以认为就是它的实体。

在发送数据时,我们需要看下套接字要进行连接的对象 IP 地址和端口号;发送数据之后,套接字里面会记录发送数据经过了多长时间,如果发送收到响应,也会进行记录。

我们来实际看下 套接字 都有哪些信息,可以在你电脑的控制台输入 netstat 命令进行查询:
image-20211202222152407

  • Proto: 表示协议类型。这里是 tcp ,如果用到了 udp 就会显示为 udp。
  • Local Address : 本机的 IP 地址。
  • Foreign Address : 通信对象的 IP 地址
  • state : 通信状态。ESTABLISHED 表示完成连接 ,CLOSE_WAIT 表示等待关闭,还有一个状态也很常见,LISTENING:等待对方连接。

当浏览器通过 Socket 库向协议栈发出 socket 调用时,协议栈就会根据申请执行创建套接字的操作。

协议栈首先会分配一个存放套接字的内存空间,然后往里面存入控制信息,这样套接字就创建好了。

连接服务器

创建好套接字后,浏览器会调用 connect ,协议栈就会将本地的套接字和服务器的套接字进行连接。

连接就是通信双方互相交换控制信息,连接操作所交换的控制信息是根据通信规则来确定的,只要双方根据规则进行连接,就能建立起连接关系,完成数据收发的准备。

控制信息

控制信息一般可以分为两类,一类是客户端和服务器相互联系时交换的控制信息,这个信息是两者建立连接、数据收发、断开连接整个通信过程都需要的信息,一般这些内容是通过 TCP 协议进行定义的。这些信息会被添加进网络包的开头,因此也叫作头部,以太网和 IP 协议也有自己的控制信息,这个信息也叫头部,为了进行区分,我们分别叫作 TCP 头部、以太网头部、IP 头部。

image-20211202224249165

这里罗列了部分 TCP 头部的信息,仅供参考。

控制信息还有一类,是保存在套接字里的,应用程序传递的信息和从通信对象接受的信息都会保存在这里,以及数据收发操作的执行状态也会在这里面。

连接操作的实际过程

连接操作的第一步就是在 TCP 模块处创建表示连接控制信息的头部。当 TCP 头部创建好后,TCP 模块会将信息传递给 IP 模块委托其进行发送。IP 执行发送后,网络包会通过网络到达服务器,服务器上的 IP 模块将接收到的数据传递给 TCP 模块,TCP 模块根据头部信息找到对应的套接字,套接字中会写入相应的信息,然后将状态改为正在连接。

于此同时,在返回响应时,会将 ACK 控制位设为 1,代表已接收到网络包。服务器 TCP 模块会将响应消息通过 IP 模块向客户端做出响应。

客户端接收到响应后,其 IP 模块将信息传递给 TCP 模块,然后通过 TCP 头部信息确认连接是否成功,SYN 等于 1 就代表成功,客户端还会将 ACK 设置为1 并发回给服务器,服务器收到这个包后才算连接操作真正的完成。

建立连接后,就可以随时进行收发数据了,在调用 close 之前,连接会一直存在。

收发数据

收发数据的触发操作是应用程序发起的,通过调研 write,指定发送数据的长度。

一般当协议栈接受到数据时可能并不会马上发出去,而是放在发送缓冲区中,为什么要这样做呢?

有些程序可能一次性会传所有数据,但有些程序会逐行传递,在这种情况下,如果收到数据就发送,可能会造成发送大量小包数据,导致效率低下。至于需要积累多少数据才发送一般是根据两方面因素来考量,一个是每个网络包的数据长度,还有一个纬度是处理时间。

网络包容纳的数据长度

首先介绍下两个名词:

**MTU:**一个网络包的最大长度,以太网中一般是1500字节,是包含头部的总长度。

MSS: 除去头部后,一个网络包所有容纳的数据最大长度。

image-20211207212858984

处理时间

当一个应用程序发送数据的频率不高时,如果每次都需要等到长度达到 MSS 才发送,就会造成等待时间过长。为了解决这种情况,协议栈会有一个计时器,如果达到一定时间,即使还远未达到 MSS 长度,也会把网络包发送出去。

ACK 机制确认网络包接收情况

当客户端向服务端发送数据时,TCP会将数据的字节数算好写在 TCP 头部,同时会生成一个随机数 当作 ACK 一并发送给服务端,服务端接受后就会根据实际收到的长度和TCP头部给的长度做对比,来确保数据没有遗漏,同时客户端还需要告知服务端是从哪个字节开始发送的,而我们的 ACK是个随机值,这时候我们就需要通过 SYN 控制位设置为1发送给服务器,这样服务器就知道其初始是从哪个字节开始发送的。

接受方收到数据后,如果数据没问题,就需要告知发送方收到了多少数据,也是通过 ACK 号的操作来返回的,这个 ACK 的值就是一共接收了多少字节。

image-20211207215300835

通过这种机制,我们就可以确认接收方是否正确收到数据,如果没有准确收到,就可以重新发送网络包。

无论网络发生何种错误,我们就都可以发现并采取补救措施。

窗口滑动

一般如果我们每发送一个网络包就等待 ACK 返回确认后再发送下一个包,这个等待 ACK 的时间啥都不做就会很浪费。

窗口滑动的概念就是每次发送一个网络包,不会等 ACK 返回就会继续发送下一个包,减少等待时间的浪费。

image-20211207220426864

但这种方式也会存在问题,假如发送方不断发送数据给接收方,接收方第一个数据还没处理完,第二个数据就来了,这些来不及处理的数据会进入接收缓冲区,数据会不断增多,就会造成溢出。避免这种方式的处理是通过接收方告知发送方自己最大能接收多少数据,发送方会根据这个值对发送的数据进行控制。

删除套接字

当我们数据收发完成后,就会启动断开机制,以 Web 为例,收发数据结束时,服务器会发起断开过程,会调用 Socket 库的 close 程序,服务器协议栈会生成一个包含断开信息的 TCP 头部,就是将 FIN 比特设置为1。协议栈会委托 IP 模块向客户端发送数据。

image-20211207222956748

当客户端接收到 FIN 为 1 的 TCP 头部时,客户端协议栈会将自己的套接字标记为进入断开操作状态,然后告知服务器已经收到 FIN 为 1的包,客户端会向服务器返回一个 ACK 号。

UDP 协议收发操作

之前我们都是以 TCP 协议讲解的数据收发操作,可以看出整个流程下来其实是挺复杂的,但是有时候可能我们并不需要这么复杂的安全校验,UDP 就可以满足一些简单的数据收发。例如像我们之前提到的 向 DNS 服务器查询 IP 地址,我们就是用的 UDP 协议。

UDP 没有 TCP 的接收确认、窗口等机制,在收发数据之前是不需要进行交换控制信息,不需要进行连接操作。

接收数据也很简单,只需要根据 IP 头部中的接收方和发送方 IP 地址,以及 UDP 头部中的接收方和发送方端口号,找到对应的套接字然后将数据交给相应的应用程序即可。

image-20211207225205810

关注小蛋,一起成长,一起进步

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-12-09 12:01:41  更:2021-12-09 12:03:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:27:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码