嵌入式學習第二十四天--網絡 服務器


服務器模型

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;
}

?
?? ? ?
?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/73284.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/73284.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/73284.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用GPTQ量化Llama-3-8B大模型

使用GPTQ量化8B生成式語言模型 服務器配置&#xff1a;4*3090 描述&#xff1a;使用四張3090&#xff0c;分別進行單卡量化&#xff0c;多卡量化。并使用SGLang部署量化后的模型&#xff0c;使用GPTQ量化 原來的模型精度為FP16&#xff0c;量化為4bit 首先下載gptqmodel量化…

防汛應急包,快速響應,守護安全

根據中國水利部統計&#xff0c;自1949年以來&#xff0c;我國幾乎每年都面臨洪水威脅&#xff0c;其中20世紀90年代后洪澇災害頻率顯著增加&#xff0c;僅1990-2009年間就發生超4000起較大災害&#xff0c;直接經濟損失近3萬億元&#xff0c;受災人口達20億人次。在2020年長江…

從 Vue 到 React:理解作用與副作用

作用 VS 副作用 響應式作用&#xff1a; 響應式作用是 Vue 響應式系統的一部分&#xff0c;它指的是跟蹤函數的依賴關系&#xff0c;并在它們的值發生變化時重新運行該函數的過程。watchEffect 是最直接的創建作用的方式&#xff08;如 watch 和 computed&#xff09;。 副作…

a = b c 的含義

簡單一句話&#xff1a; result condition && value; condition 為真取 value的值&#xff0c;condition為假就取condition的值&#xff0c;真取后假取前 // 示例 1: b 為真值 let b 1; let c 2; let a b && c; console.log(a); // 輸出: 2// 示例 2: b 為…

【大模型系列】llama.cpp本地運行大模型

上一篇鏈接: 【大模型系列】使用ollama本地運行千問2.5模型 我們講了ollama本地運行大模型&#xff0c;這里我們介紹另一種本地運行大模型的方法&#xff1a;llamacpp 軟件下載 下載地址&#xff1a;https://github.com/ggml-org/llama.cpp/releases 下載cpu版本的llamacpp&a…

PyQt基礎——簡單的圖形化界面(窗口)

一、代碼展示 import sysfrom PyQt6.QtGui import QPixmap from PyQt6.QtWidgets import QWidget, QApplication, QLabel, QLineEdit, QPushButton from PyQt6 import uic from PyQt6.QtCore import Qt# 封裝一個我的窗口類 class MyWidget(QWidget):def __init__(self):supe…

泰山派開發之—Ubuntu24.04下Linux開發環境搭建

簡介 最近翻到了吃灰已久的泰山派&#xff0c;是剛出來的時候用優惠券買的&#xff0c;當時價格挺便宜的&#xff0c;最近給它翻出來了&#xff0c;打算試試做個項目。買的泰山派容量是2G16G&#xff0c;SOC芯片使用的是RK3566&#xff0c;搭載1TOP算力的NPU&#xff0c;并且具…

HTTP 協議中常見的錯誤狀態碼(詳細介紹)

以下是 HTTP 協議中常見的錯誤狀態碼及其原因的總結&#xff0c;按錯誤類型分類整理&#xff1a; 4xx 客戶端錯誤 400 Bad Request 原因&#xff1a;請求格式錯誤&#xff0c;服務器無法解析。常見場景&#xff1a; 請求頭或請求體語法錯誤&#xff08;如 JSON/XML 格式錯誤…

kkFileView文件預覽組件部署說明

kkFileView組件部署流程指南 在數字化辦公與文件管理場景中&#xff0c;在線文件預覽功能極為關鍵。kkFileView作為一款優秀的開源在線文件預覽組件&#xff0c;支持多種格式文件的預覽&#xff0c;為企業和開發者提供了便捷的解決方案。下面將詳細介紹其部署步驟。 一、前期準…

[React Native]Stack、Tab和Drawer導航器詳解

對于StackNavigator&#xff0c;網頁[1]提到它用于頁面間的層級跳轉&#xff0c;使用棧結構管理頁面。網頁[4]和[8]詳細說明了navigationOptions的配置&#xff0c;比如標題、頭部樣式等。網頁[3]展示了如何在Stack中嵌入Tab導航&#xff0c;這可以作為組合使用的例子。 TabNa…

激光雷達產業觀察--速騰聚創發展脈絡2025.3.14

一.發展歷程 1.1 企業創立 速騰聚創的創立可追溯至2014年8月28日&#xff0c;這家充滿活力的高科技企業誕生于中國深圳。公司創始人邱純鑫是一位富有遠見的企業家&#xff0c;他的創業之路充滿了創新精神和技術洞察力。 邱純鑫的創業靈感源于他在哈爾濱工業大學深圳校區的學…

Kubernetes 網絡方案全解析:Flannel、Calico 與 Cilium 對比與選擇

文章目錄 Kubernetes 網絡方案全解析&#xff1a;Flannel、Calico 與 Cilium 對比與選擇Flannel —— 輕量級基礎網絡簡介核心特性適用場景 Calico —— 高性能與安全兼備的成熟方案簡介核心特性適用場景 Cilium —— 基于 eBPF 的下一代網絡方案簡介核心特性適用場景 深入對比…

OpenCV實現圖像分割與無縫合并

一、圖像分割核心方法 1、閾值分割 #include <opencv2/opencv.hpp> using namespace cv; int main() {Mat img imread("input.jpg", IMREAD_GRAYSCALE);Mat binary;threshold(img, binary, 127, 255, THRESH_BINARY); // 固定閾值分割imwrite("binary.…

計算機視覺算法實戰——駕駛員分心檢測(主頁有源碼)

?個人主頁歡迎您的訪問 ?期待您的三連 ? ?個人主頁歡迎您的訪問 ?期待您的三連 ? ?個人主頁歡迎您的訪問 ?期待您的三連? ? ??? 1. 領域簡介&#xff1a;駕駛員分心檢測的意義與挑戰 駕駛員分心檢測是智能駕駛安全領域的重要研究方向。據統計&#xff0c;全球每…

scoop退回軟件版本的方法

title: scoop退回軟件版本的方法 date: 2025-3-11 23:53:00 tags: 其他 前言 在軟件更新后&#xff0c;如果出現了很影響使用體驗的問題&#xff0c;那么可以把軟件先退回以前的版本進行使用&#xff0c; 但是scoop本身并沒有提供直接讓軟件回退版本的功能&#xff0c;因此…

OpenRewrite配方之import語句的順序——org.openrewrite.java.OrderImports

org.openrewrite.java.OrderImports 是 OpenRewrite 工具庫中的一個重要規則(Recipe),專為 Java 項目設計,用于自動化調整 import 語句的順序,使其符合預定義的代碼規范。從而提高代碼的一致性和可讀性。 核心功能 排序規則: 靜態導入優先:默認將靜態導入(import stati…

搭建活動報名新神器

用戶痛點 以往&#xff0c;依靠傳統的手動報名方式&#xff0c;像 Excel 表格登記或者郵件收集信息&#xff0c;在活動規模較小時或許還能應付。可一旦參與人數增多&#xff0c;問題就接踵而至&#xff1a;信息分散在不同文檔和郵件中&#xff0c;難以集中管理&#xff1b;人工…

MySQL增刪改查操作 -- CRUD

個人主頁&#xff1a;顧漂亮 目錄 1.CRUD簡介 2.Create新增 使用示例&#xff1a; 注意點&#xff1a; 3.Retrieve檢索 使用示例&#xff1a; 注意點&#xff1a; 4.where條件查詢 前置知識&#xff1a;-- 運算符 比較運算符 使用示例&#xff1a; 注意點&#xf…

設計模式C++

針對一些經典的常見的場景, 給定了一些對應的解決方案&#xff0c;這個就叫設計模式。 設計模式的作用&#xff1a;使代碼的可重用性高&#xff0c;可讀性強&#xff0c;靈活性好&#xff0c;可維護性強。 設計原則&#xff1a; 單一職責原則&#xff1a;一個類只做一方面的…

STM32上實現簡化版的AUTOSAR DEM模塊

文章目錄 摘要摘要 在一些可以不使用AUTOSAR的項目中,往往也有故障檢測和DTC存儲的需求,開發一套類似于AUTOSAR DEM模塊的軟件代碼,能夠滿足DTC的檢出和存儲,使用FalshDB代替Nvm模塊,輕松構建持久化存儲,如果你也有這樣的需求,請閱讀本篇,希望能夠幫到你。 /*********…