网络协议二

一、套接字Socket

基于 TCP UDP 协议的 Socket 编程,在讲 TCP 和 UDP 协议的时候,我们分客户端和服务端,在写程序的时候,我们也同样这样分。
在网络层,Socket 函数需要指定到底是 IPv4 还是 IPv6,分别对应设置为 AF_INET 和 AF_INET6。另外,还要指定到底是 TCP 还是 UDP。还记得咱们前面讲过的,TCP 协议是基于数据流的,所以设置为 SOCK_STREAM,而 UDP 是基于数据报的,因而设置为 SOCK_DGRAM。

监听的 Socket 和真正用来传数据的 Socket 是两个,一个叫作监听 Socket,一个叫作已连接 Socket

比喻:接待客人

想象你在家里准备接待客人,你有一个门铃和一个客厅。门铃相当于监听 Socket,而客厅相当于已连接 Socket。

  1. 监听 Socket(门铃)

    • 你家的门铃一直在等待有人按下它,这就像服务器上的监听 Socket 一直在等待新的连接请求。
    • 当有人按下门铃时,你知道有客人到访了,但你还不知道是谁,也还没有开始与客人交谈。
  2. 已连接 Socket(客厅)

    • 当你开门迎接客人,并带他们到客厅后,你就开始与客人交流了,这时候的客人就相当于已连接 Socket。
    • 在客厅里,你可以与每个客人进行独立的对话,不会相互干扰。

技术解释

在网络编程中,特别是 TCP 服务器程序中,监听 Socket 和已连接 Socket 是两个不同的概念和用途:

  1. 监听 Socket

    • 作用:用来监听和接受新的连接请求。
    • 创建:在服务器启动时创建,并绑定到特定的 IP 地址和端口。
    • 工作方式:服务器调用 listen() 方法,使这个 Socket 进入监听状态,等待客户端的连接请求。当有客户端请求连接时,服务器调用 accept() 方法,从监听 Socket 接受连接请求。
  2. 已连接 Socket

    • 作用:用来与客户端进行实际的数据传输。
    • 创建:当服务器调用 accept() 方法并成功接收一个客户端连接后,会生成一个新的已连接 Socket。这个 Socket 专门用于与该客户端进行通信。
    • 工作方式:服务器使用这个已连接 Socket 调用 send()recv() 方法,与客户端交换数据。

基于 TCP 协议的 Socket 程序函数调用过程

在这里插入图片描述

write() 和 read():适用于所有类型的文件描述符,包括 Socket,功能简单直接。
send() 和 recv():专为网络 Socket 设计,提供额外的功能和灵活性,通过 flags 参数控制行为。

基于 UDP 协议的 Socket 程序函数调用过程

对于 UDP 来讲,过程有些不一样。UDP 是没有连接的,所以不需要三次握手,也就不需要调用 listen 和 connect,但是,UDP 的的交互仍然需要 IP 和端口号,因而也需要 bind。UDP 是没有维护连接状态的,因而不需要每对连接建立一组 Socket,而是只要有一个 Socket,就能够和多个客户端通信。也正是因为没有连接状态,每次通信的时候,都调用 sendto 和 recvfrom,都可以传入 IP 地址和端口。
在这里插入图片描述

服务器如何接更多的项目?

会了这几个基本的 Socket 函数之后,你就可以轻松地写一个网络交互的程序了。就像上面的过程一样,在建立连接后,进行一个 while 循环。客户端发了收,服务端收了发。
当然这只是万里长征的第一步,因为如果使用这种方法,基本上只能一对一沟通。如果你是一个服务器,同时只能服务一个客户,肯定是不行的。这就相当于老板成立一个公司,只有自己一个人,自己亲自上来服务客户,只能干完了一家再干下一家,这样赚不来多少钱。
那作为老板你就要想了,我最多能接多少项目呢?当然是越多越好。
我们先来算一下理论值,也就是最大连接数,系统会用一个四元组来标识一个 TCP 连接。
{本机 IP, 本机端口, 对端 IP, 对端端口}
服务器通常固定在某个本地端口上监听,等待客户端的连接请求。因此,服务端端 TCP 连接四元组中只有对端 IP, 也就是客户端的 IP 和对端的端口,也即客户端的端口是可变的,因此,最大 TCP 连接数 = 客户端 IP 数×客户端端口数。对 IPv4,客户端的 IP 数最多为 2 的 32 次方,客户端的端口数最多为 2 的 16 次方,也就是服务端单机最大 TCP 连接数,约为 2 的 48 次方。
当然,服务端最大并发 TCP 连接数远不能达到理论上限。首先主要是文件描述符限制,按照上面的原理,Socket 都是文件,所以首先要通过 ulimit 配置文件描述符的数目;另一个限制是内存,按上面的数据结构,每个 TCP 连接都要占用一定内存,操作系统是有限的。

所以,作为老板,在资源有限的情况下,要想接更多的项目,就需要降低每个项目消耗的资源数目。

方式一:将项目外包给其他公司(多进程方式)

方式二:将项目转包给独立的项目组(多线程方式)

上面这种方式你应该也能发现问题,如果每次接一个项目,都申请一个新公司,然后干完了,就注销掉这个公司,实在是太麻烦了。毕竟一个新公司要有新公司的资产,有新的办公家具,每次都买了再卖,不划算。
于是你应该想到了,我们可以使用线程。相比于进程来讲,这样要轻量级的多。如果创建进程相当于成立新公司,购买新办公家具,而创建线程,就相当于在同一个公司成立项目组。一个项目做完了,那这个项目组就可以解散,组成另外的项目组,办公家具可以共用。

上面基于进程或者线程模型的,其实还是有问题的。新到来一个 TCP 连接,就需要分配一个进程或者线程。一台机器无法创建很多进程或者线程。有个C10K,它的意思是一台机器要维护 1 万个连接,就要创建 1 万个进程或者线程,那么操作系统是无法承受的。如果维持 1 亿用户在线需要 10 万台服务器,成本也太高了。

方式三:一个项目组支撑多个项目(IO 多路复用,一个线程维护多个 Socket)

当然,一个项目组可以看多个项目了。这个时候,每个项目组都应该有个项目进度墙,将自己组看的项目列在那里,然后每天通过项目墙看每个项目的进度,一旦某个项目有了进展,就派人去盯一下。

由于 Socket 是文件描述符,因而某个线程盯的所有的 Socket,都放在一个文件描述符集合 fd_set 中,这就是项目进度墙,然后调用 select 函数来监听文件描述符集合是否有变化。一旦有变化,就会依次查看每个文件描述符。那些发生变化的文件描述符在 fd_set 对应的位都设为 1,表示 Socket 可读或者可写,从而可以进行读写操作,然后再调用 select,接着盯着下一轮的变化。。

方式四:一个项目组支撑多个项目(IO 多路复用,从“派人盯着”到“有事通知”)

上面 select 函数还是有问题的,因为每次 Socket 所在的文件描述符集合中有 Socket 发生变化的时候,都需要通过轮询的方式,也就是需要将全部项目都过一遍的方式来查看进度,这大大影响了一个项目组能够支撑的最大的项目数量。因而使用 select,能够同时盯的项目数量由 FD_SETSIZE 限制。

如果改成事件通知的方式,情况就会好很多,项目组不需要通过轮询挨个盯着这些项目,而是当项目进度发生变化的时候,主动通知项目组,然后项目组再根据项目进展情况做相应的操作。

能完成这件事情的函数叫 epoll,它在内核中的实现不是通过轮询的方式,而是通过注册 callback 函数的方式,当某个文件描述符发送变化的时候,就会主动通知。

假设进程打开了 Socket m, n, x 等多个文件描述符,现在需要通过 epoll 来监听是否这些 Socket 都有事件发生。其中 epoll_create 创建一个 epoll 对象,也是一个文件,也对应一个文件描述符,同样也对应着打开文件列表中的一项。在这项里面有一个红黑树,在红黑树里,要保存这个 epoll 要监听的所有 Socket。
当 epoll_ctl 添加一个 Socket 的时候,其实是加入这个红黑树,同时红黑树里面的节点指向一个结构,将这个结构挂在被监听的 Socket 的事件列表中。当一个 Socket 来了一个事件的时候,可以从这个列表中得到 epoll 对象,并调用 call back 通知它。

这种通知方式使得监听的 Socket 数据增加的时候,效率不会大幅度降低,能够同时监听的 Socket 的数目也非常的多了。上限就为系统定义的、进程打开的最大文件描述符个数。因而,epoll 被称为解决 C10K 问题的利器

名词解释

文件描述符限制是指一个操作系统中能够同时打开的文件和网络连接的数量上限。为了理解这个概念,我们可以先了解什么是文件描述符,然后解释为什么它会限制并发 TCP 连接数。

什么是文件描述符?

在操作系统中,每个文件(包括网络连接)在打开时,都会被分配一个唯一的标识符,这个标识符就叫做文件描述符(File Descriptor,简称 FD)。文件描述符是一个非负整数,用来引用一个打开的文件或网络连接。

  • 文件:任何类型的文件,比如文本文件、图片文件等。
  • 网络连接:TCP 连接、UDP 连接等。
  • 其他资源:如管道、设备等。

文件描述符限制

操作系统对每个进程能够同时打开的文件描述符数量有限制,这是出于资源管理和安全的考虑。这个限制通常可以分为两个层次:

  1. 软限制:用户或进程可以更改的限制,一般默认较小,但可以通过修改系统设置或在程序中动态调整。
  2. 硬限制:系统级的限制,只有管理员可以更改,通常比软限制要大。

举个例子

假设你在编写一个服务器程序,这个服务器需要处理很多客户端的连接,每个连接对应一个文件描述符。

  • 默认限制操作系统可能默认限制每个进程只能打开 1024 个文件描述符。如果你有超过 1024 个客户端同时连接到服务器,新的连接将无法建立,因为文件描述符已经用完。
  • 调整限制:你可以通过修改系统配置来增加文件描述符的限制。例如,在 Linux 系统中,你可以通过修改 /etc/security/limits.conf 文件或使用 ulimit 命令来调整这个限制。

为什么文件描述符限制会影响并发连接数?

每个 TCP 连接在服务器端都需要一个文件描述符来表示和管理。如果文件描述符用完了,服务器将无法接受新的连接,即使硬件和其他资源还能够处理更多的连接。这就导致了并发 TCP 连接数远不能达到理论上的上限。


应用层协议

二、HTTP协议:看个新闻原来这么麻烦

HTTP 是基于 TCP 协议的,要先建立 TCP 连接
建立了连接以后,浏览器就要发送 HTTP 的请求。

HTTP 请求的创建

在这里插入图片描述

第一部分:请求行

GET POST PUT DELETE
POST 往往是用来创建一个资源的,而 PUT 往往是用来修改一个资源的。

第二部分:首部字段

例如,Accept-Charset,表示客户端可以接受的字符集。防止传过来的是另外的字符集,从而导致出现乱码。

再如,Content-Type是指正文的格式。例如,我们进行 POST 的请求,如果正文是 JSON,那么我们就应该将这个值设置为 JSON。

在 HTTP 协议中,Cache-ControlIf-Modified-Since 是用于控制缓存行为和条件请求的头字段。让我们通俗易懂地解释它们的作用和工作方式。

Cache-Control 头字段用于指定缓存机制的指令,这些指令告诉浏览器和中间缓存服务器如何缓存 HTTP 响应。它可以帮助提高网站性能和减少带宽消耗。

常见指令
  1. public:响应可以被任何缓存(包括浏览器、代理服务器等)缓存。

    • 例子Cache-Control: public
  2. private:响应只能被用户的浏览器缓存,不能被共享缓存(如代理服务器)缓存。

    • 例子Cache-Control: private
  3. no-cache:缓存可以存储响应,但在使用前必须先验证其有效性(向服务器发送请求确认)。

    • 例子Cache-Control: no-cache
  4. no-store:不允许缓存响应,所有内容每次都必须从服务器获取。

    • 例子Cache-Control: no-store
  5. max-age:指定响应在缓存中可以保存的最大时间(以秒为单位),在此时间内缓存内容被认为是新鲜的。

    • 例子Cache-Control: max-age=3600(缓存内容在1小时内有效)
场景:用户访问网页
  1. 第一次访问

    • 用户浏览器向服务器请求网页。
    • 服务器返回网页内容,并在响应头中包含 Cache-Control: max-age=3600Last-Modified 头字段。
    • 浏览器将网页缓存1小时。
  2. 在1小时内再次访问

    • 浏览器检查缓存,发现缓存仍然有效(未超过 max-age)。
    • 浏览器直接从缓存中加载网页,无需向服务器发送请求。
  3. 超过1小时再次访问

    • 浏览器向服务器发送请求,包含If-Modified-Since头字段,指示上次接收到的 Last-Modified 时间。
    • 服务器检查资源是否自该时间以来有修改:
      • 如果没有修改,返回 304 Not Modified,浏览器使用缓存内容。
      • 如果有修改,返回新的网页内容和新的 Last-Modified 时间,浏览器更新缓存。

HTTP 请求的发送

就是 TCP 传输

HTTP 2.0

HTTP/2 和 HTTP/1.1 是两个版本的超文本传输协议,它们有许多不同之处,主要目的是提高性能和效率。以下是 HTTP/2 和 HTTP/1.1 的主要区别,通俗易懂地解释这些技术细节:

1. 多路复用

  • HTTP/1.1:每个请求-响应对都需要一个独立的 TCP 连接。这意味着如果一个网页上有多个资源(如图片、CSS 文件、JavaScript 文件等),每个资源的请求通常需要单独的连接,导致了“队头阻塞”(Head-of-Line Blocking)问题:一个请求阻塞了,后续请求也无法进行。
  • HTTP/2:引入了多路复用技术,多个请求和响应可以在一个单一的 TCP 连接中同时进行。这样可以有效地利用网络资源,减少延迟。

2. 二进制分帧

  • HTTP/1.1:使用纯文本格式来传输数据,包括请求和响应头部。这种格式在解析时效率较低。
  • HTTP/2:使用二进制分帧层(Binary Framing Layer),将所有传输的信息(头部和数据)编码为二进制格式。这种方式更高效、解析更快,并且更容易实现多路复用。

3. 头部压缩

  • HTTP/1.1:每次请求都会携带完整的头部信息,头部信息往往很大且包含重复的内容,浪费了带宽。
  • HTTP/2:使用 HPACK 压缩算法对头部信息进行压缩,大大减少了头部的大小和冗余信息,提高了传输效率。

4. 服务器推送

  • HTTP/1.1:只有客户端可以主动请求资源,服务器只能被动响应。
  • HTTP/2:引入了服务器推送功能,服务器可以在客户端请求某个资源时,主动推送其他相关资源到客户端,这样客户端就不需要再单独请求这些资源了。例如,当客户端请求一个 HTML 页面时,服务器可以提前推送相关的 CSS 和 JavaScript 文件。

5. 流量控制

  • HTTP/1.1:没有针对流量控制的机制,所有请求-响应对共享带宽,可能导致性能不稳定。
  • HTTP/2:引入了流量控制机制,可以更好地管理和分配带宽,确保各个请求的传输速度和效率。

6. 优先级和依赖关系

  • HTTP/1.1:没有内置的请求优先级机制,所有请求的处理顺序主要取决于到达服务器的顺序。
  • HTTP/2:允许客户端为每个请求分配优先级,并建立依赖关系,使得重要的资源可以优先传输,优化了页面加载顺序和速度。
    在这里插入图片描述

QUIC

尽管 HTTP/2 引入了多路复用技术,使得多个流可以在一个 TCP 连接上并行传输,但由于底层使用的是 TCP 协议,TCP 必须保证数据包按顺序和完整性传输。如果某个数据包出现问题,整个连接上的所有数据传输都会被阻塞,直到问题数据包被正确重传和接收。这就意味着,即使在 HTTP/2 中,某个流的数据包出现问题,其他流的数据传输也会受到影响,无法完全避免队头阻塞的问题

于是,就又到了从 TCP 切换到 UDP。这就是 Google 的 QUIC 协议

机制一:自定义连接机制

我们都知道,一条 TCP 连接是由四元组标识的,分别是源 IP、源端口、目的 IP、目的端口。一旦一个元素发生变化时,就需要断开重连,重新连接。在移动互联情况下,当手机信号不稳定或者在 WIFI 和 移动网络切换时,都会导致重连,从而进行再次的三次握手,导致一定的时延。

这在 TCP 是没有办法的,但是基于 UDP,就可以在 QUIC 自己的逻辑里面维护连接的机制,不再以四元组标识,而是以一个 64 位的随机数作为 ID 来标识,而且 UDP 是无连接的,所以当 IP 或者端口变化的时候,只要 ID 不变,就不需要重新建立连接。

机制二:自定义重传机制

三、

四、

五、

六、

七、

八、

九、

十、

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ICLR24大模型提示(1/11) | BadChain:大型语言模型的后门思维链提示

【摘要】大型语言模型 (LLM) 已证明可从思路链 (COT) 提示中获益,尤其是在处理需要系统推理过程的任务时。另一方面,COT 提示也以后门攻击的形式带来新的漏洞,其中模型将在推理期间在特定的后门触发条件下输出非预期的恶意内容。发起后门攻击…

k8s牛客面经篇

k8s的pod版块: k8s的网络版块: k8s的deployment版块: k8s的service版块: k8s的探针板块: k8s的控制调度板块: k8s的日志监控板块: k8s的流量转发板块: k8s的宏观版块:

Meta的开源力作:Lexical框架,富文本的未来

引言 Lexical 是一个由 Facebook(现在称为 Meta)开源的可扩展 JavaScript Web 文本编辑器框架。 这个框架特别强调了三个核心特性:可靠性、可访问性以及高性能。 旨在为开发者创造最优的开发体验。 以下是 Lexical 框架的几个关键特点和能…

广东肇庆mes系统服务商 盈致科技

广东肇庆MES系统服务商盈致科技为企业提供专业的MES系统解决方案,帮助企业实现生产过程的数字化管理和优化。盈致科技的服务包括但不限于以下方面:MES系统定制开发:盈致科技可以根据企业的实际需求定制开发MES系统,满足企业特定的…

OJ题讲解——栈与队列

目录 一.有效的括号 1.问题描述 2.问题详解 3.代码 二.用队列实现栈 1.问题描述 2.问题详解 3.代码 三.用栈实现队列 1.问题描述 2.问题详解 3.代码 四.设计循环队列 1.问题描述 2.问题详解 3.代码 一.有效的括号 1.问题描述 OJ链接:. - 力扣&…

归并排序(分治)

归并排序 概念介绍原理解释:案例步骤:稳定性:画图理解如下 代码实现 概念介绍 归并排序(Merge Sort)是一种经典的排序算法,基于分治的思想,它将待排序数组分成两个子数组,分别排序&…

基于Python+django购物商城系统设计和实现(源码+LW+部署文档+讲解等)

💗博主介绍:✌全网粉丝1W,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 🌟文末获取源码数据库🌟 感兴趣的可以先收藏起来,还…

iPhone的5G设置怎么更改吗?设置好这些能够优化电池的使用寿命

随着5G技术的普及,iPhone用户现在可以享受到更快的网络速度,但这同时也带来了一个问题:如何在使用5G和保持电池寿命之间找到平衡?苹果公司通过引入“5G Auto”设置,为用户提供了一个智能的解决方案,但用户也…

3D模型轻量化:无损精度和细节,轻量化处理3D模型的云原生工具

随着科技的不断发展,三维模型在各个领域的应用愈加广泛。然而,传统的CAD工具生成的模型往往包含大量的面片和数据,这在进行模型查看、分享、协作以及在线展示时带来了诸多不便。模型文件过大不仅导致传输速度慢,还可能因为文件格式…

移远通信携手高通,共启智能出行新时代

5月30-31日,2024高通汽车技术与合作峰会在无锡国际会议中心举行。作为高通“汽车朋友圈”的重要一员,移远通信应邀参会,展示了数十款基于高通平台打造的车载蜂窝通信模组、C-V2X模组、智能座舱模组、Wi-Fi/蓝牙模组,适配高通多个平…

「实战应用」如何用图表控件LightningChart JS创建SQL仪表板应用(一)

LightningChart JS是Web上性能特高的图表库,具有出色的执行性能 - 使用高数据速率同时监控数十个数据源。 GPU加速和WebGL渲染确保您的设备的图形处理器得到有效利用,从而实现高刷新率和流畅的动画,常用于贸易,工程,航…

c++ - priority_queue使用和模拟实现

文章目录 一、priority_queue接口使用二、 priority_queue模拟实现三、模拟代码总览 一、priority_queue接口使用 1、函数接口与作用 接口作用priority_queue< T >构造一个空优先队列priority_queue< T >(迭代区间)通过迭代区间构造一个优先队列push(val)val入队…

计算机视觉与模式识别实验2-1 角点检测算法(Harris,SUSAN,Moravec)

文章目录 &#x1f9e1;&#x1f9e1;实验流程&#x1f9e1;&#x1f9e1;Harris算法SUSAN算法Moravec算法 &#x1f9e1;&#x1f9e1;全部代码&#x1f9e1;&#x1f9e1; &#x1f9e1;&#x1f9e1;实验流程&#x1f9e1;&#x1f9e1; Harris算法 Harris算法实现步骤&…

数据容器的通用操作、字符串大小比较 总结完毕!

1.数据容器的通用操作 1&#xff09;五类数据容器是否都支持while循环/for循环 五类数据容器都支持for循环遍历 列表、元组、字符串都支持while循环&#xff0c;集合、字典不支持&#xff08;无法下标索引&#xff09; 尽管遍历的形式不同&#xff0c;但都支持遍历操作 2&a…

在电脑端实现多个微信同时登录[使用bat脚本登录]

在电脑端实现多个微信同时登录[使用bat脚本登录] 我认为工作和生活应该分开进行&#xff0c;但往往不尽人意。 第一步&#xff0c;找到微信启动程序地址。 第二步 创建txt文本&#xff0c;写入start 你的微信启动程序地址。 start D:\微信文件\WeChat\WeChat.exe start D:\微…

The First项目报告:一场由社区驱动的去中心化加密冒险—Turbo

2023年3月14日&#xff0c;由OpenAI公司开发自回归语言模型GPT-4发布上线&#xff0c;一时之间引发AI智能领域的轩然大波&#xff0c;同时受到影响的还有加密行业&#xff0c;一众AI代币纷纷出现大幅度拉升。与此同时&#xff0c;一款名为Turbo的Meme代币出现在市场中&#xff…

在美育浸润中成长 ——中山市光后中心小学张峻皓书画作品毕业汇报展成功举办

5 月 30 号下午 3 点&#xff0c;“在美育浸润中成长——广东省中山市光后中心小学张峻皓书画作品毕业汇报展”在中山市三乡镇光后中心小学成功举行&#xff0c;本次共展出张峻皓同学近期创作书法、国画及陶瓷作品共计78幅。 广东省中山市文联兼职副主席、中山市书法家协会主席…

【距离四六级只剩一个星期!】刘晓艳四级保命班课程笔记(1)(可分享治资料~)

大家好&#xff01;距离四级考试也就只剩下一个星期左右了&#x1f635;‍&#x1f4ab;。我也是时候好好补一补四级了&#xff0c;总不能还是不过吧&#x1f62d;&#xff08;已经考了两次了&#xff09;&#xff0c;这次我一定过过过过过过&#xff0c;大家也一定要过&#x…

若依前后端分离Spring Security新增手机号登录

备忘贴 转自&#xff1a;【若依RuoYi短信验证码登录】汇总_数据库_z_xiao_qiang-RuoYi 若依 配置Security: 按照Security的流程图可知&#xff0c;实现多种方式登录&#xff0c;只需要重写三个主要的组件&#xff0c;第一个用户认证处理过滤器&#xff0c;第二个用户认证tok…

Linux Shell脚本编写指南

大家好&#xff0c;在当今快节奏的科技时代&#xff0c;自动化和高效的工作流程对于个人和组织来说变得愈发重要。而Shell脚本编写作为一种强大且广泛应用的技能&#xff0c;成为了实现自动化任务和系统管理的利器。通过编写Shell脚本&#xff0c;我们可以将繁琐的重复任务自动…