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

【网络】代理服务器收尾及高级IO

全是通俗易懂的讲解,如果你本节之前的知识都掌握清楚,那就速速来看我的笔记吧~  

自己写自己的八股!让未来的自己看懂! (全文手敲,受益良多)  

 本文主要带你了解什么是高级IO,以及常见的多路复用 接口。具体代码使用在下一篇文章


续上文收尾: 

        我们要访问目标服务器,一定会经过运营商。报文内容都会经过运营商,所以运营商可以对这些报文做分析,对非法的请求(访问外网)做拦截。有那么一种服务器,在特殊地区,但是可以访问外网,我们可以通过访问这个服务器,进而访问外网,规避运营商的检测。

        常规情况下,http默认携带的是非http的其他数据。HTTP 隧道技术是一种通过 HTTP 协议来传输非 HTTP 数据的方法,它允许在 HTTP 连接上封装其他协议(如 TCP、UDP 等)的数据,从而突破网络限制或绕过防火墙的某些规则,实现特定应用的通信。

NAT和代理服务器

路由器往往都具备 NAT 设备的功能, 通过 NAT 设备进行中转, 完成子网设备和其他子

网设备的通信过程.

  代理服务器看起来和 NAT 设备有一点像. 客户端向代理服务器发送请求, 代理服务器将

请求转发给真正要请求的服务器; 服务器返回结果后, 代理服务器又把结果回传给客户端.

那么 NAT 和代理服务器的区别有哪些呢?

  • 从应用上讲, NAT 设备是网络基础设备之一, 解决的是 IP 不足的问题. 代理服务器则是更贴近具体应用, 比如通过代理服务器进行翻墙, 另外像迅游这样的加速器,也是使用代理服务器.
  • 从底层实现上讲, NAT 是工作在网络层, 直接对 IP 地址进行替换. 代理服务器往往工作在应用层.
  • 从使用范围上讲, NAT 一般在局域网的出口部署, 代理服务器可以在局域网做,也可以在广域网做, 也可以跨网.
  • 从部署位置上看, NAT 一般集成在防火墙, 路由器等硬件设备上, 代理服务器则是一个软件程序, 需要部署在服务器上.

代理服务器是一种应用比较广的技术.

• 翻墙: 广域网中的代理.

• 负载均衡: 局域网中的代理.

高级IO

IO:输入Input输出Output。我们以读写为例:如果我们read,但是接受缓冲区没有数据,就会阻塞地等,write也一样。

  1. 应用层read&&write的时候,本质就是把数据从应用层给OS——本质就是拷贝函数
  2. IO=等待+拷贝。在等read时接受缓冲区有没有数据,write时发送缓冲区有没有空余位置。所以要进行拷贝,必须判断条件(读写事件)成立。
    什么叫做高效IO呢?
    单位时间内,IO过程中,等的比重越小,IO效率越高。几乎所有提高IO效率的策略,本质上就是让等的比重越小。

五种IO模型

  1. 阻塞式IO(read,write就是这种)
  2. 非阻塞式IO,非阻塞轮询
  3. 信号驱动式IO
  4. 多路复用,多路转接
  5. 异步IO

前4种IO称为同步IO

 阻塞式IO和非阻塞IO有什么区别?

  答:IO=等待+拷贝。等的方式不同而已,非阻塞IO可以在等的时候(非阻塞轮询)做其他事情。IO上效率没区别。

同步IO和异步IO有什么区别?

  答:二者本质是有没有参与IO,只要参与等或拷贝,就参与了IO。同步参与了IO,异步只是发起IO,没有参与IO,拿起结果就行。

同步IO和线程同步有关系吗?

  答:没有关系。同步IO是IO上的,线程同步是2个线程谁先谁后。

阻塞IO:

非阻塞IO:

信号驱动IO:

多路转接IO:

异步IO:

非阻塞IO

fcntl

一个文件描述符, 默认都是阻塞 IO.

函数原型如下.

#include <unistd.h>#include <fcntl.h>int fcntl(int fd, int cmd, ... /* arg */ );

传入的 cmd 的值不同, 后面追加的参数也不相同.

fcntl 函数有 5 种功能:

• 复制一个现有的描述符(cmd=F_DUPFD).

• 获得/设置文件描述符标记(cmd=F_GETFD 或 F_SETFD).

• 获得/设置文件状态标记(cmd=F_GETFL 或 F_SETFL).

• 获得/设置异步 I/O 所有权(cmd=F_GETOWN或 F_SETOWN).

• 获得/设置记录锁(cmd=F_GETLK,F_SETLK 或 F_SETLKW).

我们此处只是用第三种功能, 获取/设置文件状态标记, 就可以将一个文件描述符设置为非阻塞.

实现函数 SetNoBlock

基于 fcntl, 我们实现一个 SetNoBlock 函数, 将文件描述符设置为非阻塞.

void SetNoBlock(int fd) 
{int fl = fcntl(fd, F_GETFL);if (fl < 0) {perror("fcntl");return;}fcntl(fd, F_SETFL, fl | O_NONBLOCK);}

• 使用 F_GETFL 将当前的文件描述符的属性取出来(这是一个位图).

• 然后再使用 F_SETFL 将文件描述符设置回去. 设置回去的同时, 加上一个O_NONBLOCK 参数.

阻塞式正常读:                                               非阻塞:

一旦我们设置为非阻塞,如果底层fd数据没有就绪,recv/read/write/send,返回值会以出错的形式返回。A.真的出错了,B.底层没有就绪。通过errno区分!!!

多路转接——select

select只负责等,一次等待多个fd。

返回值:大于0:有n个fd就绪了,等于0:超时,没有错误,但是没有fd就绪,小于0:等待出错了。

nfds:n个fd里面最大的fd+1。

timeout是输入输出型参数:

fd_set:内核提供的数据类型,它是位图。

Fd_set *readfds 是输入输出型参数,

   输入时:用户告诉内核,我给你一个或者多个fd,你要帮我关心fd上面的读事件,如果就绪了,要告诉我。

输出时:内核告诉用户,你让我关心的多个fd中,有哪些已经就位了,你快去读吧。

比特位的位置,表示文件描述符的编号,比特位的内容表示是否需要内核关心,上面的读事件已经就绪了。

结论:fd_set是一张位图,让用户,内核之间传递fd是否就绪的信息的.注定了,使用select的时候,一定有大量的位图操作。

代码:

数据获取上来了,不可以直接读取。目前代码是单进程,建立连接的时候,不一定发消息了,所以read可能会阻塞住,必须要让select处理,将新连接交给select。

Select缺点

  1. 等待的fd是有上线的,因为位图有上线
  2. 输入输出型参数比较多,数据拷贝的频率比较高
  3. 输入输出型参数比较多,每次都要对关心的fd进行事件重置
  4. 使用第三方数组管理用户的fd,用户层需要多次遍历。内核中检测fd事件就绪,也要遍历

为了解决这些缺点,我们有另一个多路转接的方案

Poll

poll:只负责等待,

将输入输出事件进行了分离!!

Poll也有在用户层,内核方面的遍历效率问题。为了解决我们有epoll


本文主要是概念,篇幅不多,下篇文章才是重头戏!

         下一章我将详细介绍,select,poll,epoll的使用~期待你的关注👉 【A charmer】

http://www.xdnf.cn/news/1071.html

相关文章:

  • vue项目中axios统一或单独控制接口请求时间
  • WPS Office安卓版云文档同步速度与PDF转换体验测评
  • 音视频小白系统入门课-3
  • 媒体发稿攻略,解锁新闻发稿成长新高度
  • 双指针-11.盛水最多的容器-力扣(LeetCode)
  • vue作业-周报管理系统
  • python 执行顺序
  • 程序员学商务英文之Terms of Payment Packing
  • 日志文件太大,如何分卷压缩便于传输
  • pwm驱动呼吸灯
  • 【NCCL】transport建立(一)
  • Express项目实战大事件后台 API 项目(五)——文章管理
  • java集合框架day1————集合体系介绍
  • 服务器监控软件推荐
  • Python Cookbook-6.7 有命名子项的元组
  • RAG vs 微调:大模型定制化技术选型全解析
  • 10、Context:跨维度传音术——React 19 状态共享
  • 【Java核心技术卷Ⅰ-第11版学习-第3章-Java的基本程序设计结构】
  • 每日一题(9) 垃圾箱分布
  • 基于SpinrgBoot+Vue的智慧农业管理平台-031
  • 远程医疗系统如何有效防护CC攻击
  • 智慧教室电子班牌-智能管理系统源码,‌后端‌基于Spring Boot框架,前端‌使用Vue.js框架进行组件化开发
  • 在python中装饰器的使用
  • File工具总结
  • 悟空黑桃A邀请码(31187835)
  • VSCode远程图形化GDB
  • 算法 | 鲸鱼优化算法(WOA)与强化学习的结合研究
  • Dify-web开发思路
  • Pikachu靶场-SQL注入
  • STM32——相关软件安装