【网络面试(3)】浏览器委托协议栈完成消息的收发

 前面的博客中,提到过很多次,浏览器作为应用程序,本身是不具备向网络中发送网络请求的能力,要委托操作系统的内核协议栈来完成。协议栈再调用网卡驱动,通过网卡将请求消息发送出去,本篇博客就来探讨一下这个过程是如何实现的。

 浏览器与WEB服务器的交互,从总体上看可以分为4个阶段,具体如下:

  • 创建阶段: 创建客户端套接字
  • 连接阶段: 客户端套接字与服务端套接字建立连接
  • 通信阶段: 客户端和服务端的收发消息
  • 断开阶段: 断开连接并删除套接字的过程

 虽然我们说,浏览器是委托内核协议栈完成了收发消息的动作,但实际上,他们两个并不是直接交互的,和之前DNS解析器一样,浏览器会调用操作系统Socket库中的很多程序组件依次来完成上面提到的4个阶段,所以Socket库起到非常重要的作用。

1. 创建套接字阶段

 服务端程序在启动之初,会创建一个ServcerSocket实例,然后与程序的端口关联起来,然后监听端口,等待客户端连接请求的到来。

 客户端创建套接字的操作非常简单,只要浏览器调用一下Socket库中的socket()程序组件就可以了,和之前说的调用DNS客户端组件一样。接下来socket()组件就会帮助我们创建好套接字,并且把套接字描述符返回,套接字描述符和套接字一一对应,可以理解为套接字的ID,因为在计算机中可能用多个应用程序都会发起网络请求,所以会存在很多的套接字。返回的套接字描述符会被保存在内存中。

        <描述符> = socket(<使用IPv4>, <流模式>, ...);

 客户端在创建套接字之后,就可以拿着此套接字和服务端建立连接,进行收发数据的操作。每次客户端只要出示套接字描述符,协议栈就可以找到对应的套接字来处理消息了。

2. 客户端和服务端套接字连接阶段

 接下来,我们需要委托协议栈来将客户端创建的套接字和服务器那边的套接字连接起来,这一步,是借助于Socket库中的connect()组件来实现的,这个方法有三个入参,分别是:

    1. 描述符:就是上面提到的创建套接字阶段返回的描述符;
    1. 服务器IP地址:这一步已经经过前面的DNS解析器拿到了;
    1. 端口号:为了找到服务端应用程序的套接字;

 这里需要说明一下,套接字描述符只属于客户端或者服务端机器的,两者之间并不知道对方的套接字描述符是什么,所以通过描述符来识别对方机器上的套接字是没有意义的。

 通过调用connect()组件,协议栈就会执行连接操作,此时客户端和服务端的套接字就连接在一起了,可以想象成一条虚拟存在的管道流。当连接成功后,协议栈就会分别将对接对方的IP地址和端口号信息保存在自己的套接字中,方便以后的数据收发操作。

     connect(<套接字描述符>, <服务器IP地址>, <服务器端口号>, ...);

3. 收发消息的通信阶段

 当双方的套接字建立连接后,下面的事情就是把数据放入到套接字中,协议栈就会执行发送和接收的操作。同理,应用程序也是借助于Socket库中的组件来完成这些动作,具体过程如下:

  • 发送消息: 浏览器解析URL生成的HTTP消息就是我们要发送的数据,此时浏览器调用write()组件来完成数据的发送,由于连接阶段,我们的套接字中已经知道了服务端的IP地址和端口号,所以在识别出通讯对象后,数据就能发送到指定的服务器程序。

     write(<套接字描述符>, <发送数据>, <发送的数据长度>, ...);

  • 接收消息: 接收消息的操作是通过调用read()程序组件委托协议栈来完成的,调用read()函数时,需要指定服务器响应消息存放的内存地址,这一地址就是接收缓冲区,而且这块内存地址是属于应用程序(浏览器)的,因此消息就相当于直接转交给了浏览器。

     read(<套接字描述符>, <接收缓冲区>, ...);

4. 断开连接阶段

 当数据收发的过程结束,我们就需要调用Socket库中的close()组件来完成断开阶段操作了,最终管道断开,套接字本身也会删除(套接字其实本身是一块内存)。

 Web使用的HTTP协议归档,当web服务器响应结束后,应该主动执行断开操作,之后传达到客户端,客户端的套接字也会进入到断开阶段。之后,当浏览器再调用read()组件执行接收数据时,read()组件会告诉应用程序数据收发操作已结束,连接已经断开,浏览器得知后,也会调用close()进入断开阶段。

 HTTP协议将文档、图片视频等都会当成单独的对象来处理,每获取一次数据产生一次请求,就意味着创建连接、收发消息、断开连接的过程,对于同一台服务器来说显然效率是很低的。所以在后来的HTTP1.1版本中,提供了支持一次连接,收发多个请求和响应的方法,这样在一次连接后,等所有的数据请求完成后,浏览器才会主动触发断开连接的操作。

 最后总结一下,虽然我们探讨的事浏览器和服务端程序的消息收发过程,但是中间离不开Socket库的各种程序组件、内核协议栈、网卡驱动程序、网卡,只有他们相互配合,数据才能在网络中流动起来。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【操作系统】虚拟存储器

5.1 虚拟存储器概述 之前介绍的各种存储器管理方式有一个共同的特点&#xff0c;即它们都要求将一个作业全部装入内存后方能运行。于是&#xff0c;出现了下面这样两种情况&#xff1a; (1) 有的作业很大&#xff0c;其所要求的内存空间超过了内存总容量&#xff0c;作业不能全…

CDH 6.3.2集成flink 1.18 zookeeper版本不匹配Flink-yarn启动失败

CDH 6.3.2集成flink 1.18 zookeeper版本不匹配Flink-yarn不能正常启动&#xff0c;而在CHD Web页面&#xff0c;flink日志报错提示不明确&#xff0c;不能定位具体错误。CM WEB启动失败错误日志如下图所示&#xff1a; CM查看完成错误日志 [31/Dec/2023 10:45:09 0000] 26000…

EOS链Ubuntu环境Install Prebuilt Binaries(安装预构建的二进制文件)的安装

[TOC](EOS链Ubuntu环境Install Prebuilt Binaries(安装预构建的二进制文件)的安装) EOS官网&#xff1a;https://eos.io/ 第一步 Ubuntu安装命令&#xff1a; 以下有两种安装方式&#xff0c;可以任选其一&#xff1a; 本文章已经上传绑定资源&#xff0c;也可以用命令安装。…

使用.Net nanoFramework 驱动ESP32的OLED显示屏

本文介绍如何使用.Net nanoFramework 驱动ESP32的OLED显示屏。我们将会从最基础的部分开始&#xff0c;逐步深入&#xff0c;让你能够理解并实现整个过程。无论你是初学者还是有一定经验的开发者&#xff0c;这篇文章都会对你有所帮助。 1. 硬件准备 1.1 ESP32开发板 这里我们…

【Unity入门】PlayerPrefs简介及使用

目录 PlayerPrefs储存位置用例注意事项 PlayerPrefs PlayerPrefs 是Unity内置的一个静态类&#xff0c;可以用于存储一些简单的数据类型&#xff1a;int ,string ,float。 分别对应的函数为&#xff1a; SetInt()&#xff1a;保存整型数据GetInt()&#xff1a;读取整形数据Se…

推荐几个贼有意思的开源项目!

这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 Python、Java、Go、C/C、Swift...让你在短时间内感受到开源的魅力&#xff0c;对编程产生兴趣&#xff01; C 项目 1、kilo&#xff1a;不到 1 千行代码实现的迷你文本编辑器。该项…

【基础】【Python网络爬虫】【12.App抓包】reqable 安装与配置(附大量案例代码)(建议收藏)

Python网络爬虫基础 App抓包1. App爬虫原理2. reqable 的安装与配置reqable 安装教程reqable 的配置 3. 模拟器的安装与配置夜神模拟器的安装夜神模拟器的配置配置代理配置证书 4. 内联调试及注意事项软件启动顺开启抓包功reqable面板功列表部件功能列表数据快捷操作栏 夜神模拟…

【vue】Easy Player实现视频播放:

文章目录 一、效果&#xff1a;二、文档&#xff1a;三、实现&#xff1a;【1】安装插件&#xff1a;【2】引入js文件&#xff1a;【3】使用&#xff1a; 四、方法&#xff1a; 一、效果&#xff1a; 二、文档&#xff1a; GitCode - EasyPlayer.js npm-easydarwin/easyplayer…

开关电源反馈环路重要参数设计,PC817和TL431实例计算和取值详解

author&#xff1a;小高霸气 data:2021.04.16 下面介绍开关电源重要的反馈电路PC817和TL431设计和应用。 在开关电源当中&#xff0c;对稳压反馈电路的设计通常会使用TL431和PC817来配合使用。在TOP 及3842等单端反激电路中的反馈电路很多都采用TL431和PC817作为参考、隔离、取…

三菱MR-JE伺服脉冲轴应用参数设置

三菱MR-JE伺服在脉冲轴控制上的应用&#xff0c;常用参数设置如下&#xff1a; 1、常用参数 未完...

架构设计系列 5:常见架构介绍

前面讲了架构是什么&#xff0c;架构的发展史&#xff0c;架构设计的基础理论&#xff0c;这次针对常见架构设计风格进行介绍和分析。 一、MVC&#xff1a;三层架构经典 经典的 MVC 架构&#xff08;Model-View-Controller&#xff09;架构是软件系统架构设计中的经典&#xf…

安装torch(GPU版本)并在Pycharm中配置

零.前置环境 1.NVIDIA GPU Computing Toolkit已安装 版本为&#xff1a;11.6 已添加到环境变量 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\bin C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\libnvvp 在cmd中查看cuda版本 方法1&#xff1a…