Socket网络通信过程 与 IO多路复用原理

news2024/11/24 20:32:52

0、引言

        本文主要讲述Socket网络编程的基本知识、IO多路复用的select、poll、epoll实现原理以及比较,并解答了一些socket建立连接、阻塞的常见问题。

1、什么是Socket、网络通信的过程

        Socket 的中文名叫作插口,事实上,双方要进行网络通信前,各自得创建一个 Socket,这相当于客户端和服务器都开了一个“口子”,双方读取和发送数据的时候,都通过这个“口子”。

        创建 Socket 的时候,可以指定网络层使用的是 IPv4 还是 IPv6,传输层使用的是 TCP 还是 UDP。UDP 的 Socket 编程相对简单些,这里我们只介绍基于 TCP 的 Socket 编程。

        服务器的程序要先跑起来,然后等待客户端的连接和数据,我们先来看看服务端的 Socket 编程过程:

  1. 服务端调用 socket() 函数:指定网络协议IPv4、传输层协议TCP(告诉通信方怎么传输)
  2. 调用 bind() 函数绑定,给这个 Socket 绑定一个 IP 地址和端口(告诉通信方往哪里传数据)
            注:一台机器有多个网卡,每个网卡有自己的IP地址;每个程序有自己的端口号;
  3. 调用listen() 函数进行监听(监听的含义就是,看有没有客户端来发起连接)
  4. 服务端进入了监听状态后,通过调用 accept() 函数,来从内核获取客户端的连接,如果没有客户端连接,则会阻塞等待客户端连接的到来。

         那客户端是怎么发起连接的呢?
        
客户端在创建好 Socket 后,调用 connect() 函数发起连接,该函数的参数要指明服务端的 IP 地址和端口号,然后万众期待的 TCP 三次握手就开始了。
        连接建立后,客户端和服务端就开始相互传输数据了,双方都可以通过 read() 和 write() 函数来读写数据。

特别注意:

        当服务端 accept 接收一个客户端的连接请求后,它会为该连接创建一个新的 socket,并使用该 socket 来与该客户端进行通信。这个新的 socket 通常称为已连接套接字(Connected Socket),也称为通信套接字(Communication Socket)。在 TCP Socket 中,每个已连接的套接字都代表了一个客户端和服务端之间的一条连接。

        也就是说,监听套接字一般只有一个,而连接套接字可能有多个。

        在服务器处理一个客户端的数据请求时,其他客户端连接的已连接套接字并不会被阻塞或关闭,它们仍然可以发送请求,只不过服务器在阻塞模式下处理多个请求时会发生阻塞,只能一个一个处理。
        而在已连接的 socket 进行数据传输时,监听 socket 仍然处于监听状态,可以接受新的连接请求,并创建新的 socket 连接。

        对此,需要采用IO多路复用的模式来解决串行处理效率低的问题

2、IO多路复用

        在阻塞式 I/O 模式下,一个已连接套接字在进行读写操作时会阻塞当前线程(或进程),直到操作完成或超时为止。因此,当服务器接受多个客户端连接并同时监听多个已连接套接字时,在处理某个连接请求时,如果该连接未响应,当前线程就会一直被阻塞,直到该请求完成或超时。这样的处理方式会导致服务器无法同时响应多个其他客户端的请求, 而非阻塞IO模式又会导致cpu空转,效率较低。

        因此在实际应用中通常会使用多路复用 I/O 等技术来解决这个问题。服务器不会阻塞在某个连接上,而是可以同时监听多个已连接套接字,并根据事件类型进行相应的处理,以提高并发性能和吞吐量。

2.1 select/poll的方式实现多路复用

        select 实现多路复用的方式是:
        将已连接的 Socket 都放到一个FD文件描述符集合,然后调用 select 函数将文件描述符集合拷贝到内核里,让内核来检查是否有网络事件产生,检查的方式很粗暴,就是通过遍历文件描述符集合的方式,当检查到有事件产生后,将此 Socket 标记为可读或可写(0和1来表示), 接着再把整个文件描述符集合拷贝回用户态里,然后用户态还需要再通过遍历的方法找到可读或可写的 Socket,然后再对其处理。


        所以,对于 select 这种方式,需要进行 2 次「遍历」文件描述符集合,一次是在内核态里,一个次是在用户态里 ,而且还会发生 2 次「拷贝」文件描述符集合,先从用户空间传入内核空间,由内核修改后,再传出到用户空间中。
        select 使用固定长度的 BitsMap,表示文件描述符集合,而且所支持的文件描述符的个数是有限制的,在 Linux 系统中,由内核中的 FD_SETSIZE 限制, 默认最大值为 1024,只能监听 0~1023 的文件描述符。 

        poll 不再用 BitsMap 来存储所关注的文件描述符,取而代之用动态数组,以链表形式来组织,突破了 select 的文件描述符个数限制,当然还会受到系统文件描述符限制。

但是 poll 和 select 并没有太大的本质区别,都是使用「线性结构」存储进程关注的 Socket 集合,因此都需要遍历文件描述符集合来找到可读或可写的 Socket,时间复杂度为 O(n),而且也需要在用户态与内核态之间拷贝文件描述符集合,这种方式随着并发数上来,性能的损耗会呈指数级增长。

2.2 epoll实现

        epoll 通过两个方面,很好解决了 select/poll 的问题。

         第一点,epoll 在内核里使用红黑树来跟踪进程所有待检测的文件描述字,把需要监控的 socket 通过 epoll_ctl() 函数加入内核中的红黑树里,红黑树是个高效的数据结构,增删查一般时间复杂度是 O(logn),通过对这棵黑红树进行操作,这样就不需要像 select/poll 每次操作时都传入整个 socket 集合,只需要传入一个待检测的 socket,减少了内核和用户空间大量的数据拷贝和内存分配。
        第二点, epoll 使用事件驱动的机制,内核里维护了一个链表来记录就绪事件,当某个 socket 有事件发生时,通过回调函数内核会将其加入到这个就绪事件列表中,当用户调用 epoll_wait() 函数时,只会返回有事件发生的文件描述符的个数,不需要像 select/poll 那样轮询扫描整个 socket 集合,大大提高了检测的效率。

网络模型-epoll中的ET和LT

        当FD有数据可读时,我们调用epoll_wait(或者select、poll)可以得到通知。但是事件通知的模式有两种:

  • LevelTriggered:简称LT,也叫做水平触发。只要某个FD中有数据可读,每次调用epoll_wait都会得到通知。

  • EdgeTriggered:简称ET,也叫做边沿触发。只有在某个FD有状态变化时,调用epoll_wait才会被通知。

一般而言,边缘触发的方式会比水平触发的效率高。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML(一)

一.HTML的标准结构 <!doctype html> 声明文档类型<html> HTML根标签<head> 头标签<title></title> 标题标签</head><body> 主题标签...</body></html> 二.标签介绍 2.1 段落标签 1.注释标签 <!--我是一个注释--…

送外卖适合什么蓝牙耳机,推荐几款适合户外佩戴的骨传导耳机

骨传导耳机&#xff0c;是通过震动的方式将声音转化为不同频率的机械振动&#xff0c;由于不需要通过耳膜就可以听到声音&#xff0c;骨传导耳机在保留传统耳机的优点的基础上&#xff0c;解决了传统耳机不能在开放环境中使用的问题。那么在骨传导耳机中&#xff0c;究竟有哪些…

MobaXterm 常用设置

MobaXterm 是用于远程计算的工具箱&#xff0c;作为一个 Windows 应用程序&#xff0c;它为程序员、网站管理员、IT管理员和几乎所有需要以更简单的方式处理远程工作的用户量身定制了大量功能。MobaXterm 提供了所有重要的远程网络工具(SSH, X11, RDP, VNC, FTP, MOSH&#xff…

消息队列常见问题整理

前言 消息队列&#xff08;Message Queue&#xff09;&#xff0c;从广义上讲是一种消息队列服务中间件&#xff0c;提供一套完整的信息生产、传递、消费的软件系统。 消息队列所涵盖的功能远不止于队列&#xff08;Queue&#xff09;&#xff0c;其本质是两个进程传递信息的…

Java Web程序设计的学习

属于B/S结构、服务器软件&#xff1a;Apache Tomcat、 Web 项目 目录结构&#xff1a; 1.src目录&#xff1a;存放Java源文件 2.WebRoot目录&#xff1a; 存在两个子目录&#xff1a; META-INF目录 WEB-INF目录&#xff1a;&#xff08;lib目录&#xff1a;存放驱动…

Notepad++安装json插件

Notepad是Windows操作系统下的一套文本编辑器(软件版权许可证:GPL)&#xff0c;有完整的中文化接口及支持多国语言编写的功能(UTF8技术)。 Notepad功能比 Windows 中的Notepad(记事本)强大&#xff0c;除了可以用来制作一般的纯文字说明文件&#xff0c;也十分适合编写计算机程…

MySQL数据表:对数据的基础操作(增、删、查、改)以及运算符的讲解

目录 前言 一.增加数据 二.查询数据 2.1查询数据表中所有信息 2.2查询表中指定的列信息 2.3查询通过计算的列 2.4使用别名代替列名 2.5查询不带有重复值的列 2.6将查询的结果进行排序 2.7条件查询 2.7.1条件查询的种类 2.7.2使用运算符查询的讲解 2.8分页查询 …

2015年全国硕士研究生入学统一考试管理类专业学位联考写作试题

2015年1月真题&#xff1a; 四、写作&#xff1a;第56~57小题&#xff0c;共65 分。其中论证有效性分析30 分&#xff0c;论说文35 分。 56、论证有效性分析&#xff1a; 分析下述论证存在的缺陷和漏洞&#xff0c;选择若干要点&#xff0c;写一篇600 字的文章&#xff0c;对…

MyCat2介绍以及部署和读写分离/分库分表(MyCat2.0)

一&#xff0c;MyCat入门 1.什么是mycat 官网&#xff1a;http://www.mycat.org.cn/​ mycat是数据库中间件 它可以干什么&#xff1f; 读写分离数据分片&#xff1a;垂直拆分&#xff0c;水平拆分多数据源整合 2.数据库中间件 ​ 中间件&#xff1a;是一类连接软件组件和…

KSM01.2B-061C-35N-M1-HP0-SE-NN伺服电机力士乐

​ KSM01.2B-061C-35N-M1-HP0-SE-NN伺服电机力士乐 KSM01.2B-061C-35N-M1-HP0-SE-NN伺服电机力士乐 从应用对象的规模上来说&#xff1a; PLC一般应用在小型自控场所&#xff0c;比如设备的控制或少量的模拟量的控制及联锁&#xff0c;而大型的应用一般都是DCS。当然&#x…

STM32开发——DMA(数据搬运)

目录 1.DMA简介 2.从内存到内存搬运 2.1CubeMX设置 2.2函数代码 3.内存到外设 3.1CubeMX配置 3.2 函数代码 4.外设到内存 4.1CubeMX配置 4.1函数代码 1.DMA简介 DMA(Direct Memory Access&#xff0c;直接存储器访问) 提供在外设与内存、存储器和存储器、外设 与外设…

APM二次开发(二):添加一个任务

固件版本 APM copter 4.3.1 参考&#xff1a;https://ardupilot.org/dev/docs/code-overview-scheduling-your-new-code-to-run-intermittently.html APM添加任务比PX4要简单很多&#xff0c;直接在调度器里添加函数即可。 先定义一个要调度的函数my_test() 然后加到调度器中…

C++ [STL容器反向迭代器]

本文已收录至《C语言和高级数据结构》专栏&#xff01; 作者&#xff1a;ARMCSKGT STL容器反向迭代器 前言正文适配器反向迭代器反向迭代器框架默认成员函数反向迭代器的遍历反向迭代器的比较反向迭代器数据访问反向迭代器代码测试反向迭代器 最后 前言 我们知道STL大部分容器…

(2023最新版)互联网大厂1120道Java面试真题附答案详解

很多 Java 工程师的技术不错&#xff0c;但是一面试就头疼&#xff0c;10 次面试 9 次都是被刷&#xff0c;过的那次还是去了家不知名的小公司。 问题就在于&#xff1a;面试有技巧&#xff0c;而你不会把自己的能力表达给面试官。 应届生&#xff1a;你该如何准备简历&#…

5.3.4 因特网的路由协议(四)BGP协议

5.3.4 因特网的路由协议&#xff08;四&#xff09;BGP协议 我们学习的RIP协议&#xff08;5.3.2 因特网的路由协议&#xff08;二&#xff09;基于距离向量算法的RIP协议&#xff09;和OSPF协议&#xff08;5.3.3 因特网的路由协议&#xff08;三&#xff09;OSPF协议&#x…

Python真的对初学者友好吗?其实可以从以下几点就能看出(收藏)

本文内容里我给大家分享的是一篇关于学习python有哪些必要条件&#xff0c;需要的朋友们可以学习下。 编程零基础&#xff0c;可以学习 Python 吗&#xff1f;这是很多初学者经常问我的一个问题。 当然&#xff0c;在计算机方面的基础越好&#xff0c;对学习任何一门新的编程…

强制使用本地GNSS作为时钟源带来的思考

1.背景知识 BMCA&#xff08;最佳时钟源选择算法&#xff09;&#xff1a;它是在PTP网络里面用来选择最佳时钟源的一种常见算法&#xff0c;它的执行过程包含一下四步&#xff1a; 时钟源发现&#xff1a;在网络中的PTP设备会交换时钟源信息。每个设备会公告自己的时钟源特性&…

联想拯救者电脑触摸板用不了了

文章目录 问题分析解决1. 解决方法一2. 解决方法二3. 解决方法三 问题 电脑触摸板用不了了&#xff0c;无论使用怎样的操作均未能完成对鼠标的操作 分析 这是因为被误触了“游戏模式”&#xff0c;就会出现“防误触”开关 解决 1. 解决方法一 &#xff08;开机输入密码前…

汽车EDI:如何与SAS建立 EDI 连接?

SAS Automotive Systems &#xff08;以下简称为&#xff1a;SAS&#xff09;是一家全球领先的汽车零部件制造商&#xff0c;总部位于德国。该公司专注于汽车电子技术和系统集成领域&#xff0c;为世界各大汽车制造商提供创新的解决方案。 EDI&#xff08;电子数据交换&#x…

MFC扩展库BCGControlBar Pro v33.5亮点 - Ribbon Bar等全新升级

BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中&#xff0c;并为您节省数百个开发和调试时间。 BCGControlBar专业版 v33.5已正式发布了&#xff0c;此版本包含了Ribbon&#xff08;功能区&#xff09;自定义…