当前位置: 首页 > news >正文

【网络面试(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库的各种程序组件、内核协议栈、网卡驱动程序、网卡,只有他们相互配合,数据才能在网络中流动起来。

在这里插入图片描述

相关文章:

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

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

Kotlin: Jetpack — ViewModel简单应用

ViewModel 概览 Android Jetpack 的一部分。 ViewModel 类是一种业务逻辑或屏幕级状态容器。它用于将状态公开给界面&#xff0c;以及封装相关的业务逻辑。 它的主要优点是&#xff0c;它可以缓存状态&#xff0c;并可在配置更改后持久保留相应状态。这意味着在 activity 之…...

【Java技术专题】「攻破技术盲区」攻破Java技术盲点之unsafe类的使用指南(打破Java的安全管控— sun.misc.unsafe)

Java后门机制 — sun.misc.unsafe 打破Java的安全管控关于Unsafe的编程建议实例化Unsafe后门对象使用sun.misc.Unsafe创建实例单例模式处理实现浅克隆&#xff08;直接获取内存的方式&#xff09;直接使用copyMemory原理分析 密码安全使用Unsafe类—示例代码 运行时动态创建类超…...

私有云平台搭建openstack和ceph结合搭建手册

OpenStack与云计算 什么是云&#xff1f; 如何正确理解云&#xff0c;可以从以下几个方面。 云的构成。 用户&#xff1a;对用户而言是透明无感知的&#xff0c;不用关心底层构成&#xff0c;只需要知道利用云完成自己任务即可。 云提供商&#xff1a;对云资产管理和运维。 云…...

debug mccl 02 —— 环境搭建及初步调试

1, 搭建nccl 调试环境 下载 nccl 源代码 git clone --recursive https://github.com/NVIDIA/nccl.git 只debug host代码&#xff0c;故将设备代码的编译标志改成 -O3 (base) hipperhipper-G21:~/let_debug_nccl/nccl$ git diff diff --git a/makefiles/common.mk b/makefiles/…...

ros python 接收GPS RTK 串口消息再转发 ros 主题消息

代码是一个ROS(Robot Operating System)节点,用于从GPS设备读取RTK(实时动态)数据并通过ROS主题发布。 步骤: 导入必要的模块: rospy 是ROS的Python库,用于ROS的节点、发布者和订阅者。serial 用于串行通信。NavSatFix 和 NavSatStatus 是从GPS接收的NMEA 0183标准消息…...

2024年网络安全竞赛-页面信息发现任务解析

页面信息发现任务说明: 服务器场景:win20230305(关闭链接)在渗透机中对服务器信息收集,将获取到的服务器网站端口作为Flag值提交;访问服务器网站页面,找到主页面中的Flag值信息,将Flag值提交;访问服务器网站页面,找到主页面中的脚本信息,并将Flag值提交;访问服务器…...

ARM DMA使用整理

Direct Memory Access&#xff0c; 直接存储访问。同SPI,IIC,USART等一样&#xff0c;属于MCU的一个外设&#xff0c;用于在不需要MCU介入的情况下进行数据传输。可以将数据从外设传输到flash&#xff0c;也可以将数据从flash传输到外设&#xff0c;或者flash内部数据移动。 它…...

移动通信原理与关键技术学习(第四代蜂窝移动通信系统)

前言&#xff1a;LTE 标准于2008 年底完成了第一个版本3GPP Release 8的制定工作。另一方面&#xff0c;ITU 于2007 年召开了世界无线电会议WRC07&#xff0c;开始了B3G 频谱的分配&#xff0c;并于2008 年完成了IMT-2000&#xff08;即3G&#xff09;系统的演进——IMT-Advanc…...

光明源@智慧厕所技术:优化生活,提升卫生舒适度

在当今数字科技飞速发展的时代&#xff0c;我们的日常生活正在经历一场革命&#xff0c;而这场革命的其中一个前沿领域就是智慧厕所技术。这项技术不仅仅是对传统卫生间的一次升级&#xff0c;更是对我们生活品质的全方位提升。从智能感应到数据分析&#xff0c;从环保设计到舒…...

【Bootstrap学习 day13】

Bootstrap5 下拉菜单 下拉菜单通常用于导航标题内&#xff0c;在用户鼠标悬停或单击触发元素时显示相关链接列表。 基础的下拉列表 <div class"dropdown"><button type"button" class"btn btn-primary dropdown-toggle" data-bs-toggl…...

Shell:常用命令之dirname与basename

一、介绍 1、dirname命令用于去除文件名中的非目录部分&#xff0c;删除最后一个“\”后面的路径&#xff0c;显示父目录。 语法&#xff1a;dirname [选项] 参数 2、basename命令用于打印目录或者文件的基本名称&#xff0c;显示最后的目录名或文件名。 语法&#xff1a;basen…...

Linux-v4l2框架

框架图 从上图不难看出&#xff0c;v4l2_device作为顶层管理者&#xff0c;一方面通过嵌入到一个video_device中&#xff0c;暴露video设备节点给用户空间进行控制&#xff1b;另一方面&#xff0c;video_device内部会创建一个media_entity作为在media controller中的抽象体&a…...

VPC网络架构下的网络上数据采集

介绍 想象这样一个场景&#xff0c;一开始在公司里&#xff0c;所有的部门的物理机、POD都在一个经典网络内&#xff0c;它们可以通过 IP 访问彼此&#xff0c;没有任何限制。因此有很多系统基于此设计了很多点对点 IP 直连的访问&#xff0c;比如中心控制服务器 S 会主动访问物…...

模拟算法(模拟算法 == 依葫芦画瓢)万字

模拟算法 基本思想引入算法题替换所有的问号提莫攻击Z字形变换外观数列数青蛙 基本思想 模拟算法 依葫芦画瓢解题思维要么通俗易懂&#xff0c;要么就是找规律&#xff0c;主要难度在于将思路转换为代码。 特点&#xff1a;相对于其他算法思维&#xff0c;思路比较简单&#x…...

QtApplets-SystemInfo

QtApplets-SystemInfo ​ 今天是2024年1月3日09:18:44&#xff0c;这也是2024年的第一篇博客&#xff0c;今天我们主要两件事&#xff0c;第一件&#xff0c;获取系统CPU使用率&#xff0c;第二件&#xff0c;获取系统内存使用情况。 ​ 这里因为写博客的这个本本的环境配置不…...

vue3防抖函数封装与使用,以指令的形式使用

utils/debounce.js /*** 防抖函数* param {*} fn 函数* param {*} delay 暂停时间* returns */ export function debounce(fn, delay 500) {let timer nullreturn function (...args) {// console.log(arguments);// const args Array.from(arguments)if (timer) {clearTim…...

Hive学习(13)lag和lead函数取偏移量

hive里面lag函数 在数据处理和分析中&#xff0c;窗口函数是一种重要的技术&#xff0c;用于在数据集中执行聚合和分析操作。Hive作为一种大数据处理框架&#xff0c;也提供了窗口函数的支持。在Hive中&#xff0c;Lag函数是一种常用的窗口函数&#xff0c;可以用于计算前一行…...

Centos Unable to verify the graphical display setup

ERROR: Unable to verify the graphical display setup. 在Linux下安装Oracle时 运行 ./runInstaller 报错 ERROR: Unable to verify the graphical display setup. This application requires X display. Make sure that xdpyinfo exist under PATH variable. No X11 DISPL…...

Java 说一下 synchronized 底层实现原理?

Java 说一下 synchronized 底层实现原理&#xff1f; synchronized 是 Java 中用于实现同步的关键字&#xff0c;它保证了多个线程对共享资源的互斥访问。底层实现涉及到对象头的 Mark Word 和锁升级过程。 synchronized 可以用于方法上或代码块上&#xff0c;分别对应于方法…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...