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

【网络】代理服务器收尾及高级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】

相关文章:

  • 组网技术-BGP技术,IS-IS协议,VRRP技术
  • 路由与路由器
  • Kubernetes finalize | namespace卡Terminatingfinalizers删除失败
  • 5G + 物联网:智能世界的催化剂,如何用Python打造下一代IoT应用?
  • 分布式之CAP原则:理解分布式系统的核心设计哲学
  • BBR 的 minRTT 采集问题
  • 数据库性能优化(sql优化)_分布式优化思路02_yxy
  • Android-KeyStore安全的存储系统
  • Vue3-全知识点
  • go 编译的 windows 进程(exe)以管理员权限启动(UAC)
  • Redis 共享和独立集群两种模式各自的优缺点是什么?
  • 【AI工具】2025年主流自动化技术(供参考)
  • 表格识别版面还原分析-GO语言集成-表格文字识别接口
  • 微信小程序 van-dropdown-menu
  • 2026《数据结构》考研复习笔记五(栈、队列)
  • MQTTX + MCP:MQTT 客户端秒变物联网 Agent
  • 安宝特科技 | AR眼镜在安保与安防领域的创新应用及前景
  • 激光SLAM算法综述
  • 基于Python的多光谱遥感数据处理与分类技术实践—以农作物分类与NDVI评估为例
  • Linux 系统监控大师:Glances 工具详解助力自动化
  • 几百元的工资优势已不能吸引人才流动,江苏多地探讨“抢人”高招
  • 外汇局:4月以来外汇市场交易保持平稳,跨境资金延续净流入
  • 云南一季度GDP为7490.99亿元,同比增长4.3%
  • 中共中央、国务院印发《关于实施自由贸易试验区提升战略的意见》
  • 电子产品已拆封,还能申请“七天无理由退货”吗?上海法院这样判
  • 诺奖得主等数十位经济学家发表宣言反对美关税政策