Linux网络编程系列之服务器编程——阻塞IO模型
Linux网络编程系列 (够吃,管饱)
1、Linux网络编程系列之网络编程基础
2、Linux网络编程系列之TCP协议编程
3、Linux网络编程系列之UDP协议编程
4、Linux网络编程系列之UDP广播
5、Linux网络编程系列之UDP组播
6、Linux网络编程系列之服务器编程——阻塞IO模型
7、Linux网络编程系列之服务器编程——非阻塞IO模型
8、Linux网络编程系列之服务器编程——多路复用模型
9、Linux网络编程系列之服务器编程——信号驱动模型
一、什么是阻塞IO模型
服务器阻塞IO模型是一种IO模型,其中服务器在处理INGRESS和EGRESS网络数据流时阻塞,并且无法处理其他连接请求。当服务器接收到一个连接请求时,它将读取数据直到读取完成,然后进行处理并发送响应,这期间,该连接请求将会阻塞其他连接请求的处理。
二、特性
1、阻塞IO调用,当服务器没有数据可读或者没有缓冲区可写入时,服务器将被阻塞。
2、每个连接都需要创建一个新的线程或进程来处理,因此服务器开销和资源占用会很大。
3、每个连接需要消耗一定的内存资源来存储相关信息,如连接状态和IO缓冲区等。
4、无法处理大量并发连接请求,可能会导致连接的延迟和响应时间过长。
5、对于大数据传输,阻塞IO可能会一次性读取所有数据并占用大量内存,从而导致服务器崩溃或性能下降。
6、由于阻塞IO模型无法实时处理并发连接请求,因此无法适应高并发、高吞吐量的应用场景。
三、使用场景
1、小规模的网络应用,如小型HTTP服务器、FTP服务器等。
2、对并发连接数量要求不高的网络应用,如内部OA系统、ERP系统等。
3、数据传输量较小的网络应用,如即时聊天应用、邮件系统等。
4、对实时响应要求不高的网络应用,如批处理任务、数据备份等。
5、对于资源受限的系统,如嵌入式系统、移动设备等,阻塞IO模型也可以用于网络应用。
四、模型框架(通信流程)
1、建立套接字。使用socket()
2、设置端口复用。使用setsockopt()
3、绑定自己的IP地址和端口号。使用bind()
4、设置监听。使用listen()
5、循环阻塞等待,接收新的客户端连接。使用accept()
6、为连接上来的客户端创建一条线程。使用pthread_create()
7、关闭套接字。使用close()
五、相关函数API接口
这里TCP服务通信的API在本系列其他博客中已经有大量讲解,这里省略,忘记了朋友可以点击本文开头上面对应的链接查看。
六、案例
使用阻塞IO模型结合TCP协议,完成服务器通信演示,使用nc命令模拟客户端。
// 阻塞IO模型TCP服务器的案例#include <stdio.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <arpa/inet.h> #include <pthread.h>#define MAX_LISTEN 50 // 最大能处理的连接数 #define SERVER_IP "192.168.64.128" // 记得改为自己IP #define SERVER_PORT 20000 // 不能超过65535,也不要低于1000,防止端口误用struct ClientInfo {int fd;uint16_t port;char ip[20]; };// 线程的例程函数 void *recv_routinue(void *arg) {int ret = 0;char recv_msg[128] = {0};struct ClientInfo client = *((struct ClientInfo*)arg);pthread_detach(pthread_self()); // 设置强制分离while(1){memset(recv_msg, 0, sizeof(recv_msg));ret = recv(client.fd, recv_msg, sizeof(recv_msg), 0);if(ret == 0){printf("[%s:%d] disconnect\n", client.ip, client.port);pthread_exit(0);}else if(ret > 0){printf("[%s:%d] send data: %s\n", client.ip, client.port, recv_msg);}} }int main(int argc, char *argv[]) {// 1、建立套接字,指定IPV4网络地址,TCP协议int sockfd = socket(AF_INET, SOCK_STREAM, 0);if(sockfd == -1){perror("socket fail");return -1;}// 2、设置端口复用(推荐)int optval = 1; // 这里设置为端口复用,所以随便写一个值int ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));if(ret == -1){perror("setsockopt fail");close(sockfd);return -1;}// 3、绑定自己的IP地址和端口号(不可以省略)struct sockaddr_in server_addr = {0};socklen_t addr_len = sizeof(struct sockaddr);server_addr.sin_family = AF_INET; // 指定协议为IPV4地址协议server_addr.sin_port = htons(SERVER_PORT); // 端口号server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); // IP地址ret = bind(sockfd, (struct sockaddr*)&server_addr, addr_len);if(ret == -1){perror("bind fail");close(sockfd);return -1;}// 4、设置监听ret = listen(sockfd, MAX_LISTEN);if(ret == -1){perror("listen fail");close(sockfd);return -1;}uint16_t port = 0;char ip[20] = {0};struct sockaddr_in client_addr = {0};printf("wait client connect...\n");while(1){// 5、接受连接请求int new_client_fd = accept(sockfd, (struct sockaddr*)&client_addr, &addr_len);if(new_client_fd == -1){perror("accept fail");close(sockfd);return -1;}else{memset(ip, 0, sizeof(ip));strcpy(ip, inet_ntoa(client_addr.sin_addr));port = ntohs(client_addr.sin_port);printf("[%s:%d] connect\n", ip, port);struct ClientInfo client = {0};client.fd = new_client_fd;client.port = port;strcpy(client.ip, ip);// 创建线程,一个客户端对应一个线程pthread_t tid;pthread_create(&tid, NULL, recv_routinue, (void*)&client);}}// 7、关闭套接字close(sockfd);return 0; }
七、总结
阻塞IO模型适用于系统资源有限,小规模通信的场景,无法适应高并发、高吞吐量的应用场景。通常做法是一个客户端对应一个线程,这样极度消耗系统资源,因此也无法处理大规模的客户端连接请求。
相关文章:
Linux网络编程系列之服务器编程——阻塞IO模型
Linux网络编程系列 (够吃,管饱) 1、Linux网络编程系列之网络编程基础 2、Linux网络编程系列之TCP协议编程 3、Linux网络编程系列之UDP协议编程 4、Linux网络编程系列之UDP广播 5、Linux网络编程系列之UDP组播 6、Linux网络编程系列之服务器编…...
排序算法-基数排序法(RadixSort)
排序算法-基数排序法(RadixSort) 1、说明 基数排序法与我们之前讨论的排序法不太一样,并不需要进行元素之间的比较操作,而是属于一种分配模式排序方式。 基数排序法比较的方向可分为最高位优先(Most Significant Di…...
nginx绑定tomcat与tomcat联合使用的配置(nginx反向代理tomcat的配置说明)
nginx反向代理tomcat通信配置 (内容来自网上,注解部分才是原创) 切记: url的意思就是 unifed resource location 统一资源定位 其中location就是定位的意思 所以上文中的location就有 对应匹配的 url 标识的资源的相关配置之…...
【Java】nextInt()后面紧接nextLine()读取不到数据/InputMismatchException异常的解决方案
错误如下: 有时候还会抛出InputMismatchException异常 看!我只输入了一个5,并没有给str赋值,它就已经将结果打印出来了!这就意味着,str是读取到了数据的,只不过这个数据并不是我们想要的输入的…...
【传输层协议】UDP/TCP结构特点与原理(详解)
文章目录 1. UDP1.1 UDP结构1.2 UDP特点1. 无连接2. 不可靠3. 面向数据报4. 缓冲区5. 大小受限6. 无序性 2. TCP2.1 TCP结构2.2 TCP特点1. 有连接2. 可靠性3. 面向字节流4. 拥塞控制5. 头部开销 2.3 TCP原理1. 确认应答(安全机制)2. 超时重传(…...
哪种网站适合物理服务器
哪种网站适合物理服务器 看到独立服务器这一词语,相信大家脑海立马就浮现出了它的种种优势,但是有优势就伴随着也有一定的弊端,比如说它的空间大、特殊的的组件配置,权限配置等,但是成本却非常的高,那么我…...
uni-app集成使用SQLite
一、打开uni-app中SQLite 二、封装sqlite.js module.exports {dbName: chat, // 数据库名称dbPath: _doc/chat.db, // 数据库地址,推荐以下划线为开头 _doc/xxx.db/*** Description: 创建数据库 或 有该数据库就打开* author: ZXL* createTime: 2023-10-12 09:23:10* Copyr…...
Qt不能安装自己想要的版本,如Qt 5.15.2
使用在线安装工具安装Qt5.15.2时,发现没有Qt 5的相关版本,只有Qt 6的版本,这时选择右边的Archive,再点击筛选,这时就会出现之前的Qt版本。...
学信息系统项目管理师第4版系列28_组织级项目管理和量化项目管理
1. OPM 1.1. 旨在确保组织开展正确项目并合适地分配关键资源 1.1.1. 有助于确保组织的各个层级都了解组织的战略愿景、实现愿景的措施、组织目标以及可交付成果 1.2. 业务评估是建立OPM框架的必要组件 1.3. OPM3 是组织级项目管理成熟度模型,可用于评估组织项目…...
Bean实例化的三级缓存
在Spring框架中,Bean实例化的三级缓存(三级缓存也称为三级缓存机制)是用于缓存Bean定义的一种机制,用于管理和加速Spring容器中Bean的创建和初始化过程。三级缓存包括了singletonObjects、earlySingletonObjects 和 singletonFact…...
Jenkins+Gitlab+Docker(Dockerfile)部署
Docker部署运行 上一篇内容中使用Jenkins(运行服务器)Gitlab(代码存储库)Webhook(网络钩子)的方式部署运行我们的项目。需要我们在服务器上做好很多相关的环境配置及依赖。 那么假如有这样一个场景:需要把不同技术栈的项目部署到同一台服务器上运行。比如PH…...
Web前端-Vue2+Vue3基础入门到实战项目-Day4(组件的三大组成部分, 组件通信, 案例-组件版小黑记事本, 进阶语法)
Web前端-Vue2Vue3基础入门到实战项目-Day4 组件的三大组成部分(结构/样式/逻辑)scoped样式冲突data是一个函数 组件通信组件通信语法父传子子传父props详解什么是propsprops检验props与data的区别 非父子(扩展)事件总线 (event bus)provide - inject 案例 - 小黑记事本(组件版)…...
【大模型应用开发教程】01_大模型简介
C1 大模型简介 一. 什么是LLM(大语言模型)?1. 发展历程2. 大语言模型的概念LLM的应用和影响 二、大模型的能力和特点1. 大模型的能力1.1 涌现能力(emergent abilities)1.2 作为基座模型支持多元应用的能力1.3 支持对话…...
Flume 简介及基本使用
1.Flume简介 Apache Flume 是一个分布式,高可用的数据收集系统。它可以从不同的数据源收集数据,经过聚合后发送到存储系统中,通常用于日志数据的收集。Flume 分为 NG 和 OG (1.0 之前) 两个版本,NG 在 OG 的基础上进行了完全的重构…...
行业追踪,2023-10-11
自动复盘 2023-10-11 凡所有相,皆是虚妄。若见诸相非相,即见如来。 k 线图是最好的老师,每天持续发布板块的rps排名,追踪板块,板块来开仓,板块去清仓,丢弃自以为是的想法,板块去留让…...
Linux:进程控制
目录 一、进程创建 写时拷贝 二、进程终止 echo $? 如何终止进程 _exit与exit 三、进程等待 进程等待的必要性 进程等待的操作 wait waitpid status 异常退出情况 status相关宏 options 四、进程程序替换 1、关于进程程序替换 2、如何进行进程程序替换 程序…...
HTTP中的GET方法与POST方法
1、GET 和 POST方法之间的区别 根据 RFC 规范,GET 的语义是从服务器获取指定的资源,这个资源可以是静态的文本、页面、图片视频等。GET 请求的参数位置一般是写在 URL 中,URL 规定只能支持 ASCII,所以 GET 请求的参数只允许 ASCI…...
2023年10月16日-10月22日,(光追+ue+osg继续按部就班进行即可。)
根据月计划, 本周计划如下: 2023年10月16日-10月22日,光追10.7-10.13,ue rpg(p47-p53),ue5底层渲染01A19-01B4,osg29,osg30,filament文档每天看 落实到天就是 2023年10月16日光追10.7,ue rpg(p47),ue5底层渲染01A19,o…...
【Docker】命令使用大全
【Docker】命令使用大全 目录 【Docker】命令使用大全 简述 Docker 的主要用途 基本概念 容器周期管理 run start/stop/restart kill rm pause/unpause create exec 容器操作 ps inspect top attach events logs wait export port 容器 rootfs 命令 c…...
查找算法:二分查找、插值查找、斐波那契查找
二分查找 查找的前提是数组有序 思路分析 代码实现 # 二分查找(递归法实现) # 找到一个相等的值就返回该值的下标 def binary_search(arr: list, find_val: int, left: int, right: int):mid (left right) // 2 # 寻找数组中间位置的下标if left &…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
