嵌入式学习第二十四天--网络 服务器
服务器模型
tcp服务器:
socket
bind
listen
accept
recv/send
close
1.支持多客户端访问
//单循环服务器
socket
bind
listen
while(1)
{
accept
while(1)
{
recv/send
}
}
close
2.支持多客户端同时访问 (并发能力)
并发服务器
socket
bind
listen
while(1)
{
connf = accept
pid_t pid = fork();
if(pid > 0)
{
continue;
}else if (pid == 0)
{
while(1) //负责 与 客户端通信的
{
recv/send
}
}
}
close
2.1进程
socket
bind
listen
while(1)
{
connf = accept
pid_t pid = fork();
//出错处理
if (pid == 0)
{
while(1) //负责 与 客户端通信的
{
recv/send
}
}
}
close
2.2线程
void *handle_client(void *arg)
{
while(1) //子线程中 负责 与 客户端通信的
{
recv/send
}
}
socket
bind
listen
while(1)
{
connf = accept
pthread_create();
//出错处理
}
close
-------------------------------------------------------------------------
三种服务器模型比较
1.单循环服务器
2.并发服务器
进程
线程
1、简单循环服务器
http
web 服务器,apache--》cgi,php,perl,IIS--》asp,NGIX,Nlighty
while(1)
{
newfd = accept();
recv();
close(newfd);
}
特点:可以接入多个客户端的信息。
缺点:数据通信过程短,客户端只能一次有效。
实时性效果差。
2、fork循环服务器===>每次有链接则fork一个子进程为该
链接处理通信过程,父进程继续等待新链接。
while(1)
{
newfd = accept();
pid = fork()
if(pid == 0)
{
///接收数据
}
if(pid < 0)
{
perror("fork");
return -1;
}
waitpid()
}
特点:可以完成多个进程的实时交互,信息的完整性可以保证。
缺点:回收资源不方便,每次fork 占用系统资源多。
可能出现僵尸进程
多线程:
特点:
创建速度快,调度快
缺点:
线程共享进程资源,稳定性,安全性 较差
3.并发的服务器模型 ---更高程度上的并发
IO模型
阻塞IO
非阻塞IO
1、阻塞IO
用的最多。
读阻塞。
写阻塞。
2、非阻塞IO
-1 errno EAGAIN whild(1){read()break;}忙等待
control
cntl
3、IO多路复用
4、信号驱动IO SIGIO ---异步
5, 并行模型 进程,线程
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );
功能:修改指定文件的属性信息。
参数:fd 要调整的文件描述符
cmd 要调整的文件属性宏名称
... 可变长的属性值参数。
返回值:成功 不一定,看cmd
失败 -1;
int fcntl(int fd, int cmd, ... /* arg */ );
//驱动:
//1.驱动程序 ---- 驱使硬件工作起来的程序
让灯亮起来
eg:修改文件的非阻塞属性:
int flag ;
flag = fcntl(fd,F_GETFL,0); ///获取fd文件的默认属性到flag变量中。
flag = flag | O_NONBLOCK; ///将变量的值调整并添加非阻塞属性
fcntl(fd,F_SETFL,flag); ///将新属性flag设置到fd对应的文件生效。
以上代码执行后的阻塞IO将变成非阻塞方式。
信号驱动IO
//signal
1.fcntl --- 设置 信号接受者
flags = fcntl(fd,F_GETFL); //获得当前标志
fcntl(fd,F_SETFL,flags|O_ASYNC); //异步通信的标志
//同步 通信
//异步 通信
2.将该程序 和 SIGIO信号关联起来
fcntl(fd,F_SETOWN,pid);
3.设置信号处理函数
signal
owner //所有者
缺点:
处理的数量有限 (超过了1个不好判断了)
/---client1
/
server <--------------->|-----client2
\
\---client3
| --->A
/---client1(子进程/线程)-- | --->B
/ | --->C
server <--------------->|-----client2(子进程/线程)-- | --->D
\ | --->E
\---client3(子进程/线程)-- | --->F
| --->G
stdin //读
stdout //写
stderr //--写出错信息
IO多路服用
多路 --- 多个输入输出
复用 --- 复用同一个进程或线程
select //linux提供实现Io多路复用函数
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout);
功能:
io多路复用函数
参数:
nfds //三个集合中最大的文件描述符 + 1
readfds //关心的 读操作的 文件描述符的集合
writefds //关心的 写操作的 文件描述符的集合
exceptfds //关心的 异常操作的 文件描述符的集合
timeout //
NULL --- select 阻塞操作
timeout --- 设定超时时间 > 0 等 这么长时间
== 0 不阻塞
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
返回值:
成功 表示 就绪的文件描述符的数量
失败 -1 && errno设置
void FD_CLR(int fd, fd_set *set); //clear --- 将fd从 set中清除
int FD_ISSET(int fd, fd_set *set); //判断 set 表中 fd是否就绪
void FD_SET(int fd, fd_set *set); //将fd设置(添加)到set中
void FD_ZERO(fd_set *set); //表示将set表清零
注意:
1. select 函数在监控到 有fd就绪后,
它会把未就绪的fd清除掉,每次需要重新获取
2. 超时一次后,时间的变量值为为0
如果,需要每次都有超时时间,需要每次重新给值
//单循环服务器
//第1路IO fgets --收键盘 --- 打印出来 --- stdin 能不能读?
//第2路IO 读管道数据 -- 修改 --- 发回去 --- 管道 能不能读?
select
1.建一张表
放 要监控 的文件描述符
readfds();
2.添加 要监控的文件描述符 到表中
FD_SET()
3.select
eg:
1. 管道双向通信:
A.c B.c
---------A2B----------------->
<--------B2A-----------------
A.c代码如下:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <stdlib.h>
//./a.out fifo_A2B fifo_B2A
int main(int argc, const char *argv[])
{if (argc != 3){printf("Usage: %s <fifo_A2B> <fifo_B2A>\n",argv[0]);return -1;}if(mkfifo(argv[1],0666) < 0 && errno != EEXIST){perror("mkfifo fail");return -1;}if(mkfifo(argv[2],0666) < 0 && errno != EEXIST){perror("mkfifo fail");return -1;}int fd1 = open(argv[1],O_WRONLY);int fd2 = open(argv[2],O_RDONLY);if (fd1 < 0 || fd2 < 0){perror("open fail");return -1;}//1.准备表 fd_set readfds;FD_ZERO(&readfds);//2.添加要监控的 fd2FD_SET(0,&readfds);FD_SET(fd2,&readfds);int nfds = fd2 + 1;int i = 0;char buf[1024];while (1){fd_set backfds = readfds;int ret = select(nfds,&backfds,NULL,NULL,NULL);if (ret < 0){perror("select fail");return -1;}if (ret > 0){for (i = 0; i < nfds; ++i){if (FD_ISSET(i,&backfds)){if (i == 0){printf("> ");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1] = '\0';write(fd1,buf,strlen(buf)+1);if (strncmp(buf,"quit",4) == 0){printf("1 exit......\n");exit(0);}}else if (i == fd2){printf("c> ");read(fd2,buf,sizeof(buf));printf("%s \n",buf);if (strncmp(buf,"quit",4) == 0){printf("2 exit......\n");exit(0);}}}}}}return 0;
}
B.c代码如下:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#include <stdlib.h>//./a.out fifo_A2B fifo_B2A
int main(int argc, const char *argv[])
{if (argc != 3){printf("Usage: %s <fifo_A2B> <fifo_B2A>\n",argv[0]);return -1;}if(mkfifo(argv[1],0666) < 0 && errno != EEXIST){perror("mkfifo fail");return -1;}if(mkfifo(argv[2],0666) < 0 && errno != EEXIST){perror("mkfifo fail");return -1;}int fd1 = open(argv[1],O_RDONLY);int fd2 = open(argv[2],O_WRONLY);if (fd1 < 0 || fd2 < 0){perror("open fail");return -1;}//1.准备表 fd_set readfds;FD_ZERO(&readfds);//2.添加要监控的 fd2FD_SET(0,&readfds);FD_SET(fd1,&readfds);int nfds = fd1 + 1;int i = 0;char buf[1024];while (1){fd_set backfds = readfds;int ret = select(nfds,&backfds,NULL,NULL,NULL);if (ret < 0){perror("select fail");return -1;}if (ret > 0){for (i = 0; i < nfds; ++i){if (FD_ISSET(i,&backfds)){if (i == 0){printf("> ");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1] = '\0';write(fd2,buf,strlen(buf)+1);if (strncmp(buf,"quit",4) == 0){printf("1 exit......\n");exit(0);}}else if (i == fd1){printf("c> ");read(fd1,buf,sizeof(buf));printf("%s \n",buf);if (strncmp(buf,"quit",4) == 0){printf("2 exit......\n");exit(0);}}}}}}return 0;
}
相关文章:
嵌入式学习第二十四天--网络 服务器
服务器模型 tcp服务器: socket bind listen accept recv/send close 1.支持多客户端访问 //单循环服务器 socket bind listen while(1) { accept while(1) { recv/send } } close 2.支持多客户端同时访问 (并发能力) 并发服务器 socket bind …...
tcp/ip协议配置参数有哪些?tcp/ip协议需要设置的参数有哪些
TCP/IP协议的配置参数是确保网络设备能够正确接入互联网并与其他设备进行通信的关键设置。这些参数主要包括以下几个方面: 1. IP地址 定义:IP地址是网络中设备的唯一标识符,用于标识和定位设备。它由32位二进制数组成,通常采用点…...
我有点担心开始AI中台了
有个特点历史教训是很难吸取的 从大数据开始就是一窝蜂的去搞,不管有没有什么数据量。反正要来个Hadoop。其实有些企业数据一块硬盘都放得下。 微服务来了,也不管自己的系统是不是适合微服务。我个人经验得出,to B和to G的业务场景…...
《用Python+PyGame开发双人生存游戏!源码解析+完整开发思路分享》
导语 "你是否想过用Python开发一款可玩性高的双人合作游戏?本文将分享如何从零开始实现一款类《吸血鬼幸存者》的生存射击游戏!包含完整源码解析、角色系统设计、敌人AI逻辑等核心技术点,文末提供完整代码包下载!" 哈…...
优选算法系列(1. 双指针_上)
目录 双指针 一:移动零(easy) 题目链接:移动零 解法: 代码: 二:复写零(easy) 题目链接:复写零 编辑 解法: 代码: 三:快乐…...
永洪科技深度分析实战,零售企业的销量预测
随着人工智能技术的不断发展,智能预测已经成为各个领域的重要应用之一。现在,智能预测技术已经广泛应用于金融、零售、医疗、能源等领域,为企业和个人提供决策支持。 智能预测技术通过分析大量的数据,利用机器学习和深度学习算法…...
c语言笔记 函数参数的等价(上)
这三种写法在 C 语言中是等价的,因为它们都用于声明一个指向二维数组的指针,或者用于声明一个二维数组作为函数参数。它们的等价性源于 C 语言中数组和指针之间的密切关系。让我们逐一分析这三种写法: 在C语言中,当数组作为函数参…...
hive面试题--left join的坑
student 表: 课程表course: 1、key为null, 不关联 select * from student s left join course c on s.id c.s_id;2、on中过滤条件 与 where 过滤条件区别 on and c.id<>‘1001’ 先过滤右表数据,然后与左表关联 select * from student s le…...
CEH与OSCP:网络安全认证对比分析
在网络安全领域,渗透测试被视为至关重要的一环,帮助企业检测和修复系统漏洞。为提升行业标准,许多认证应运而生,其中CEH和OSCP作为行业认可度较高的认证,广泛被网络安全从业者选择。尽管这两者都涉及渗透测试领域&…...
HTML 属性详解:为网页元素赋予更多功能
在构建网页的过程中,HTML 是基础的标记语言,而 HTML 属性则是为 HTML 元素提供附加信息的重要组成部分。 一、属性的基本概念与使用 属性通常出现在 HTML 标签的开始标签内,以 “name"value"” 的形式存在。这里的 “name” 是属…...
Ceph(2):Ceph简介
1 Ceph简介 Ceph使用C语言开发,遵循LGPL协议开源。Sage Weil(Ceph论文发表者)于2011年创立了以Inktank公司主导Ceph的开发和社区维护。2014年Redhat收购inktank公司,并发布Inktank Ceph企业版(ICE)软件,业务场景聚焦云…...
国产编辑器EverEdit - 设置文件类型关联为EverEdit
1 设置-文件关联 1.1 应用场景 文件关联是指在文件管理器中双击某类型的文件,操作系统自动调用可以打开该文件的应用程序,比如:用户双击XXXX.txt文件,系统默认会使用记事本打开该文件。 由于各行各业都会定义特有的文件类型&…...
2025网络安全工程师:软考新挑战与职业发展探析
网络安全工程师的崛起 随着信息技术的迅猛发展,网络安全问题日益凸显,网络安全工程师这一职业逐渐受到社会各界的广泛关注。特别是在2025年,随着各项网络安全法规的完善和实施,网络安全工程师的角色愈发重要。他们不仅是企业信息…...
设计模式之建造者模式:原理、实现与应用
引言 建造者模式(Builder Pattern)是一种创建型设计模式,它通过将复杂对象的构建过程分解为多个简单的步骤,使得对象的创建更加灵活和可维护。建造者模式特别适用于构建具有多个组成部分的复杂对象。本文将深入探讨建造者模式的原…...
【Leetcode 每日一题 - 补卡】2070. 每一个查询的最大美丽值
问题背景 给你一个二维整数数组 i t e m s items items,其中 i t e m s [ i ] [ p r i c e i , b e a u t y i ] items[i] [price_i, beauty_i] items[i][pricei,beautyi] 分别表示每一个物品的 价格 和 美丽值 。 同时给你一个下标从 0 0 0 开始的整数数…...
雪藏HsFreezer(游戏冻结工具) v2.21
HsFreezer 是一款让你可以随心冻结游戏的软件(游戏暂停软件、系统优化软件、进程管理软件),想玩就玩,想停就停,快捷键随心瞬发,单锁模式极致的丝滑切换,当然,不止适用游戏。更有丰富的特色系统优化功能。 PC主机,win掌机,笔记本--无脑装就对了,超大按键超大列表,触控盲操,非常巴…...
2019年蓝桥杯第十届CC++大学B组真题及代码
目录 1A:组队(填空5分_手算) 2B:年号字符(填空5分_进制) 3C:数列求值(填空10分_枚举) 4D:数的分解(填空10分) 5E:迷宫…...
前端安全面试题汇总及参考答案
目录 简述 XSS 攻击的原理及三种常见类型(存储型、反射型、DOM 型) 如何在前端防御 XSS 攻击?列举编码、过滤、CSP 策略的具体实现方式 富文本编辑器场景下如何安全处理用户输入的 HTML 内容? 如何通过 HttpOnly 属性增强 Cookie 安全性?它与 XSS 防御的关系是什么? …...
修复ubuntu下找不到音频设备的问题
出现问题的状态: ALSA 已正确识别到 ZOOM H2n 设备(card 1)sounddevice 库(依赖 PortAudio)未能正确枚举设备 修复方法: 1. 强制 sounddevice 使用 ALSA 后端 默认情况下,sounddevice 可能尝…...
⭐LeetCode周赛 3468. 可行数组的数目——暴力与数学⭐
⭐LeetCode周赛 3468. 可行数组的数目——暴力与数学⭐ 示例 1: 输入:original [1,2,3,4], bounds [[1,2],[2,3],[3,4],[4,5]] 输出:2 解释: 可能的数组为: [1, 2, 3, 4] [2, 3, 4, 5] 示例 2: 输入&…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
