網絡編程4-并發服務器、阻塞與非阻塞IO、信號驅動模型、IO多路復用..

一、并發服務器

1、單循環服務器(順序處理)????????

????????一次只能處理一個客戶端連接,只有當前客戶端斷開連接后,才能接受新的客戶端連接

2、多進程/多線程并發服務器

while(1) {
connfd = accept(listenfd);
pid = fork(); ?// 或 pthread_create()
if (pid == 0) {
// 子進程/線程處理通信
recv(connfd, ...);
send(connfd, ...);
close(connfd);
exit(0); // 或 pthread_exit
}
close(connfd); // 父進程關閉已交給子進程的 connfd
}

優點:

  • 實現真正并發

  • 客戶端可長時間通信

缺點:

  • 創建/銷毀進程或線程開銷大

  • 資源占用高(內存、CPU)

  • 存在僵尸進程問題(需 waitpid() 回收)

二、IO 模型分類(5種)

1、阻塞IO模型

  • 常見阻塞IO模型:
    • i--讀 scanf、getchar、fgets、read、recv
    • o--寫 管道:讀端存在,寫管道 ?寫操作阻塞>>>>內存不足,寫不進去便阻塞了

  • 優點:簡單、方便、要等 效率不高

2、?非阻塞IO模型

1)以讀為例:

  • 特點:需要不停去看,資源開銷大

2)實現方法

方法一:open() 時指定

int fd = open("fifo", O_RDONLY | O_NONBLOCK);

方法二:運行時用 fcntl() 修改

int flag = fcntl(fd, F_GETFL, 0);
flag |= O_NONBLOCK;
fcntl(fd, F_SETFL, flag);

  • 注意事項
  • ?適用于 read/write 等系統調用。 對 recv() 可使用 MSG_DONTWAIT 標志實現非阻塞

3)示例

方法一

方法二

3、信號驅動IO模型

1)使用 SIGIO 信號通知數據到達,異步但支持有限

  • 有數據發個信號,然后系統調用
  • 通知粒度粗:僅能告知 “有 IO 事件”,無法區分事件類型與細節

2)利用函數:fcntl 實現

3)實現步驟

// 1. 設置文件描述符支持異步通知
int flags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, flags | O_ASYNC);

// 2. 設置信號接收者(當前進程)
fcntl(fd, F_SETOWN, getpid());

// 3. 注冊信號處理函數
signal(SIGIO, sig_handler);

  • 不足之處
    • 支持的文件類型有限(如 socket、tty)

    • 不適合大量連接場景

    • 實際應用較少

4)示例

4、異步 IO 模型

信號驅動IO和一步IO區別

核心結論信號驅動 IO異步 IO
異步能力的完整性“半異步”:僅解決 “IO 就緒通知”,未解決 “數據拷貝異步”“全異步”:從 “IO 就緒” 到 “數據拷貝完成” 全程異步
內核與應用的職責劃分內核僅通知 “就緒”,數據拷貝需應用程序主動做內核包辦 “就緒檢測 + 數據拷貝”,應用程序僅用結果
工業界定位早期異步 IO 的過渡方案,已被淘汰現代高并發 / 高性能 IO 的標準方案

????????簡單來說:信號驅動 IO 是 “讓內核喊你‘飯好了’,但你得自己去盛飯”;現代異步 IO 是 “內核把‘飯盛好端到你面前’,你直接吃就行”—— 后者才是真正意義上 “無感知等待、無主動操作” 的異步 IO

5、IO多路復用模型

1)概念

????????一個線程監控多個文件描述符(fd),當其中任意一個就緒時通知程序進行處理

????????n個客戶端-->>用一個線程或進程服務器去答復

? ? ? ? 優點:避免創建大量線程/進程,節省資源,適合高并發場景(如 Web 服務器)

? ? ? ? 常見函數:select()、poll()、epoll()

2)函數介紹

① select

頭文件:????????#include <sys/select.h>

函數原型:

????????????????int select(int nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout);

功能:????????實現IO多路復用

參數:

????????nfds //是關心的文件描述符中最大的那個文件描述符 + 1

????????readfds //代表 要關心 的 讀操作的文件描述符的集合

????????writefds //代表 要關心 的 寫操作的文件描述符的集合 >>> 與read類似

????????exceptfds //代表 要關心 的 異常的文件描述符的集合 >>> 與read類似(error--2)

????????timeout //超時 設置一個超時時間

? ? ? ? ? ? ? ? //NULL 表示select是一個阻塞調用

????{0,0}:非阻塞效果

????{sec, usec}:指定超時

????????????????時間最小單位寫到ms

返回值:????????

????????????????成功:就緒的 fd 數量(>0)

????????????????超時:返回 0

????????????????失敗:返回 -1

輔助宏函數:

????????????????FD_ZERO(fd_set *set); ? ? ? ?????????// 清空集合
FD_SET(int fd, fd_set *set); ????????// 添加 fd 到集合
FD_CLR(int fd, fd_set *set);???????? // 從集合中移除 fd
FD_ISSET(int fd, fd_set *set);? ? ??// 判斷 fd 是否在集合中

基本實現流程

文字版過程

  • 建立一張表 >>>監控 目前只關心讀
    • fd_set readfds;一張表
    • FD_ZERO(&readfds);清空表(初始化)
  • 將要監控的文件描述符 添加到表中
    • FD_SET(0,&readfds);//stdin
    • FD_SET(fd,&readfds);//建的管道或者文件描述符
  • 準備參數
    • maxfds 是關心的文件描述符中最大的那個文件描述符 + 1
      • int maxfds = fd + 1;
    • 每次系統調用只會留下就緒的文件描述符(每次監控都會重新遍歷一遍)
      • fd_set backfds; //設置這個等于最初的表
  • 一般在循環內進行系統調用
  • 具體內容如下
  • 最前面建立tcp網絡連接的基本步驟

  • 利用select函數實現步驟

  • 加上定時定次功能

優點
  • 內核負責輪詢,減少用戶態頻繁切換

  • 支持跨平臺(Windows/Linux 均可用

缺點
  • 最大監聽數受限:FD_SETSIZE 默認 1024(Linux)

  • 每次調用需重置 fd_set:內核會修改集合,必須每次重新 FD_SET

  • 用戶態與內核態拷貝開銷大

  • 返回后仍需遍歷所有 fd 才能知道哪個就緒

  • 效率隨 fd 數量增長下降明顯

知識點
  • stdin????????--->0
  • stdout? ? ? --->1
  • error? ? ? ? --->2

② poll

頭文件:????????#include <poll.h>

函數原型:? int poll(struct pollfd *fds, nfds_t nfds, int timeout);

功能:????????????實現IO多路復用

參數:????????

struct pollfd *fds?:struct pollfd {
int ? fd; ? ? ? // 文件描述符
short events; ? // 關注的事件(輸入)
short revents; ?// 實際發生的事件(輸出)
};

nfds_t nfds:表示要監控的文件描述符的數量

timeout?:時間值?

返回值:????????

????????????????成功 表示 就緒的數量 ;0 超時情況下表示 沒有就緒實際

????????????????失敗 -1

事件標志:

????????????????POLLIN:數據可讀(等價于 select 的讀)

基本實現流程

優點
  • 無 1024 限制:只要系統允許打開足夠多 fd

  • 無需重置集合:eventsrevents 分離

  • 更清晰的事件機制

  • 效率更高:僅遍歷傳入的數組,不遍歷整個 fd 范圍

缺點
  • 每次調用仍需將整個 fds[] 拷貝到內核

  • 返回后仍需遍歷全部元素查找就緒 fd

  • 時間復雜度仍是 O(n),連接數多時性能下降

③ epoll

< 水平觸發 >

????????只要緩沖區有數據就持續觸發

結果展現

epoll_create????????????????

函數原型:????????int epoll_create(int size);

功能:? ? ? ? ? ? ??創建 epoll 實例

參數:? ? ? ? ? ? ??size:提示內核初始分配空間大小(現已忽略)

返回值:? ? ? ? ? 成功??epoll 文件描述符(用于后續操作)

? ? ? ? ? ? ? ? ?? ? ? ??失敗 -1

注意事項:??????使用完需 close(epfd)

epoll_ctl() ???????

函數原型:????????int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

功能:? ? ? ? ? ? ???控制監聽列表

參數:? ? ? ? ? ? ??epfd:epoll 句柄(epoll_create 返回

? ? ? ? ? ? ? ? ? ? ? ? ?op :操作類型

????????????????????????????????EPOLL_CTL_ADD

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??EPOLL_CTL_DEL

????????????????????????????????EPOLL_CTL_MOD

? ? ? ? ? ? ? ? ? ? ? ? ?fd:要監聽的目標文件描述符

? ? ? ? ? ? ? ? ? ? ? ? event:事件結構體? ?struct epoll_event

返回值:? ? ? ? ? 成功??epoll 文件描述符(用于后續操作)

? ? ? ? ? ? ? ? ?? ? ? ??失敗 -1

struct epoll_event

epoll_event?結構體:

struct epoll_event {
uint32_t ? ? events; ? // 監聽的事件類型
epoll_data_t data; ? ? // 用戶數據(共用體)
};

typedef union epoll_data {
void ? ?*ptr;
int ? ? ?fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;

常見事件類型
事件含義
EPOLLIN可讀
EPOLLOUT可寫
EPOLLRDHUP對端關閉連接(TCP 半關閉)
EPOLLERR錯誤(自動監聽)
EPOLLHUP掛起(自動監聽)
EPOLLET邊沿觸發模式(Edge Triggered)
EPOLLONESHOT觸發一次后失效,需重新注冊
epoll_wait() ????????

函數原型:????????int epoll_wait(int epfd,
struct epoll_event *events,
int maxevents,
int timeout);

功能:? ? ? ? ? ? ??等待事件發生

參數:? ? ? ? ? ? ??epfd:epoll 句柄(epoll_create 返回? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ? ?events:用戶提供的數組,用于接收就緒事件

? ? ? ? ? ? ? ? ? ? ? ? ?maxevents:最大接收事件數(通常 10~100

? ? ? ? ? ? ? ? ? ? ? ? timeout:超時(單位 ms )

????????????????????????????????-1:永久阻塞

????????????????????????????????0:非阻塞

????????????????????????????????>0:等待指定毫秒

?????????????????????????????????????????????? ? ? ??

返回值:? ? ? ? ? 成功??就緒事件數量(無需遍歷所有 fd)

? ? ? ? ? ? ? ? ?? ? ? ??失敗 -1

tcp 實現epoll并發服務器

封裝添加和刪除函數

完整內容

#include "head.h"int add_fd(int listenfd,int epfd)     //將文件描述符添加到 epoll 監控列表
{struct epoll_event ev; //定義結構體ev.events = EPOLLIN; //表示監控可讀事件(文件描述符有數據可讀時觸發)ev.data.fd = listenfd;if (epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev))//epoll_ctl添加、修改、刪除監控的文件描述符{perror("epoll_ctl add fail");return -1;}return 0;
}
int del_fd(int fd,int epfd)
{if (epoll_ctl(epfd,EPOLL_CTL_DEL,fd,NULL)){perror("epoll_ctl del fail");return -1;}return 0;}
int main(void)
{int serfd = socket(AF_INET,SOCK_STREAM,0);if (serfd < 0){perror("fail to socke");return -1;}struct sockaddr_in seraddr;seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50000);seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");if (bind(serfd,(const struct sockaddr *)&seraddr,sizeof(seraddr)) < 0){perror("bind fial");return -1;}if (listen(serfd,5) < 0){perror("listen fail");return -1;}struct sockaddr_in cliaddr;bzero(&cliaddr,0);socklen_t len = sizeof(cliaddr);/************正片開始******************/char buf[1024] = {0};int epfd = epoll_create(1); //創建,返回一個用于操作的文件描述符efd//括號內要求大于0的值就行add_fd(serfd,epfd);  //添加serfd到epoll監控int t = 3000;struct epoll_event ret_ev[1024];   //可以容納的個數while (1){int ret = epoll_wait(epfd,ret_ev,10,t); //等待事件發生,超時時間為3000ms//ret_ev數組用于存儲發生的事件//就序最多處理 10 個事件printf("ret = %d\n",ret);if (ret < 0)        //出錯處理{perror("epoll fail");return -1;}if (ret > 0)        //遍歷每個事件{int i = 0;for (i = 0; i < ret; i++){if (ret_ev[i].data.fd == serfd)    { int connfd = accept(serfd,(struct sockaddr *)&cliaddr,&len);if (connfd < 0){perror("accept fail");return -1;}printf("----client connect---\n");printf("client ip:%s\n",inet_ntoa(cliaddr.sin_addr));printf("port :%d\n",ntohs(cliaddr.sin_port));//添加到表里add_fd(connfd,epfd);}else //如果不是serfd我們就要開始收數據了{recv(ret_ev[i].data.fd,buf,sizeof(buf),0);printf("buf = %s\n",buf); if (0 == strncmp(buf,"quit",4)){del_fd(ret_ev[i].data.fd,epfd);    //從epfd內刪除close(ret_ev[i].data.fd);}}}}}close(serfd);return 0;
}
< 邊緣觸發 >

????????僅在狀態變化時觸發一次(必須配合非阻塞 IO)

? ? ? ? 兩種情況:

????????正常數據:實際只能觸發一次,但數據還在,利用循環可以打印出來,但是讀完數據就沒有了()---n <0

????????quit退出:實際只能觸發一次,但數據還在,利用循環可以打印出來,讀完數據就沒有了,---n= 0

主要改變

注意事項:? ? ? ?

????????????????fd 必須設置為 非阻塞

????????????????必須一次性讀完所有數據(直到 read() 返回 EAGAIN

????????????????否則會丟失后續事件

結果展現

具體水平觸發的代碼區別(改動的地方)

完整代碼

#include "head.h"
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <poll.h>
#include <sys/epoll.h>#include <unistd.h>
#include <fcntl.h>int add_fd(int fd, int epfd)
{struct epoll_event ev;ev.events = EPOLLIN | EPOLLET;// EPOLLET(ET)邊緣觸發//$$$--改1--$$$ev.data.fd = fd; //標準輸入 if ( epoll_ctl(epfd,EPOLL_CTL_ADD, fd, &ev)){perror("epoll_ctl add fail");return -1;}	return 0;
}int del_fd(int fd, int epfd) //刪除 
{//struct epoll_event ev;//ev.events = EPOLLIN;//ev.data.fd = fd; //標準輸入 if ( epoll_ctl(epfd,EPOLL_CTL_DEL, fd, NULL)){perror("epoll_ctl add fail");return -1;}	return 0;
}//$$$$$$$$$$--改2--$$$$$$$$$$$$$$$
void set_nonblock(int fd)
{int flags = fcntl(fd,F_GETFL);flags = flags | O_NONBLOCK;fcntl(fd,F_SETFL,flags);return;
}int main(int argc, char const *argv[])
{//step1 socket int fd = socket(AF_INET,SOCK_STREAM,0);if (fd < 0){perror("socket fail");return -1;}struct sockaddr_in seraddr;bzero(&seraddr,sizeof(seraddr));seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50000);seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");//step2 bind if (bind(fd,(const struct sockaddr *)&seraddr,sizeof(seraddr)) < 0){perror("connect fail");return -1;}//step3 listenif (listen(fd,5) < 0){perror("listen fail");return -1;}struct sockaddr_in cliaddr;bzero(&cliaddr,0);socklen_t len = sizeof(cliaddr);//1.準備表 int epfd = epoll_create(1);if (epfd < 0){perror("epoll_create fail");return -1;}//2.添加 fd add_fd(fd,epfd);char buf[1024] = {0};struct epoll_event ret_ev[10];while (1){int ret =epoll_wait(epfd,ret_ev,10,-1);if (ret < 0){perror("epoll fail");return -1;}if (ret > 0){int i = 0;for (i = 0; i < ret; ++i){if (ret_ev[i].data.fd == fd) //listenfd {int connfd = accept(fd,(struct sockaddr *)&cliaddr,&len);if (connfd < 0){perror("accept fail");return -1;}printf("---client connect---\n");printf("client ip:%s\n",inet_ntoa(cliaddr.sin_addr));printf("port: %d\n",ntohs(cliaddr.sin_port));//設置非阻塞set_nonblock(connfd);//添加到表中add_fd(connfd,epfd);}else //$$$$$$$$$$--改3--$$$$$$$$$$$$$$${while(1){int n =  recv(ret_ev[i].data.fd,buf,1,0);printf("n = %d buf = %s\n",n,buf);if (n < 0 && errno != EAGAIN) //正常數據{ perror("recv ");del_fd(ret_ev[i].data.fd,epfd);close(ret_ev[i].data.fd);}if (n== 0 || strncmp(buf,"quit",4) == 0) //退出{del_fd(ret_ev[i].data.fd,epfd);close(ret_ev[i].data.fd);}sleep(1);}}}}} return 0;
}

3)函數對比

特性selectpollepoll
平臺兼容性高(POSIX)僅 Linux
最大連接數~1024無限制(但性能差)無限制
時間復雜度O(n)O(n)O(1)
用戶/內核拷貝每次全量拷貝每次全量拷貝共享內存
是否修改輸入參數是(需備份)否(revents 分離)
觸發模式僅 LT僅 LTLT + ET
遍歷開銷高(需遍歷所有 fd)中(遍歷數組)低(只處理就緒)
適用場景小規模連接、跨平臺中小規模連接大規模高并發(如 Nginx)

4)應用建議

場景推薦方案
小型工具程序(<100 連接)select(簡單、跨平臺)
中等規模服務(幾百連接)pollselect
高并發服務器(數千以上)epoll(Linux)
需跨平臺(如 Windows)selectlibevent/libuv 封裝

5)總結

整體使用思路:

????????1.準備監控表

????????2.添加監控的文件描述符

????????3.調用函數監控事件發生

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

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

相關文章

在 WSL2-NVIDIA-Workbench 中安裝Anaconda、CUDA 13.0、cuDNN 9.12 及 PyTorch(含完整環境驗證)

在 WSL-NVIDIA-Workbench&#xff08;NVIDIA AI Workbench & Ubuntu 22.04&#xff09;中 安裝 Anaconda、CUDA 13.0、cuDNN 9.12 及 PyTorch 步驟也可參閱&#xff1a; 在WSL2-Ubuntu中安裝Anaconda、CUDA13.0、cuDNN9.12及PyTorch&#xff08;含完整環境驗證&#xf…

Shell編程核心入門:參數傳遞、運算符與流程控制全解析

Shell編程核心入門&#xff1a;參數傳遞、運算符與流程控制全解析 在Linux/Unix系統中&#xff0c;Shell作為命令解釋器和腳本語言&#xff0c;是自動化運維、批量處理任務的核心工具。掌握Shell腳本的參數傳遞、運算符使用和流程控制&#xff0c;能讓你從“手動執行命令”升級…

如何用 Kotlin 在 Android 手機開發一個應用程序獲取網絡時間

使用 NTP 協議獲取網絡時間在 build.gradle 文件中添加以下依賴&#xff1a;implementation commons-net:commons-net:3.6創建 NTP 時間獲取工具類&#xff1a;import org.apache.commons.net.ntp.NTPUDPClient import org.apache.commons.net.ntp.TimeInfo import java.net.In…

python智慧交通數據分析可視化系統 車流實時檢測分析 深度學習 車流量實時檢測跟蹤 軌跡跟蹤 畢業設計?

博主介紹&#xff1a;?全網粉絲50W&#xff0c;前互聯網大廠軟件研發、集結碩博英豪成立軟件開發工作室&#xff0c;專注于計算機相關專業項目實戰6年之久&#xff0c;累計開發項目作品上萬套。憑借豐富的經驗與專業實力&#xff0c;已幫助成千上萬的學生順利畢業&#xff0c;…

計算機視覺第一課opencv(四)保姆級教學

目錄 簡介 一、輪廓檢測 1.查找輪廓的API 2.代碼分析 2.1.圖像二值化處理 2.2輪廓檢測 2.3輪廓繪制 2.4輪廓面積計算 2.5輪廓周長計算 2.6篩選特定面積的輪廓 2.7查找最大面積的輪廓 2.8繪制輪廓的外接圓 2.9繪制輪廓的外接矩形 二、輪廓的近似 三、模板匹配 簡…

基于Vue2+elementUi實現樹形 橫向 合并 table不規則表格

1、實現效果 共N行&#xff0c;但是每一列對應的單元格列數固定&#xff0c;行數不固定2、實現方式說明&#xff1a;使用的是vue2 elementUI表格組件 js實現<template><div class"table-container" ><el-table height"100%" :span-metho…

深度學習在計算機視覺中的應用:對象檢測

引言 對象檢測是計算機視覺領域中的一項基礎任務&#xff0c;目標是在圖像或視頻幀中識別和定位感興趣的對象。隨著深度學習技術的發展&#xff0c;對象檢測的準確性和效率都有了顯著提升。本文將詳細介紹如何使用深度學習進行對象檢測&#xff0c;并提供一個實踐案例。 環境準…

node.js 安裝步驟

在Node.js中安裝包通常通過npm(Node Package Manager)來完成,這是Node.js的包管理工具。以下是安裝Node.js和通過npm安裝包的基本步驟: 1. 安裝Node.js 方法一:使用nvm(Node Version Manager) 推薦使用nvm來安裝Node.js,因為它允許你安裝多個Node.js版本,并輕松地在…

面試-故障案例解析

一、NFS故障&#xff0c;造成系統cpu使用率低而負載極高。故障概述: 公司使用NFS為web節點提供共享存儲服務,某一天下午發現web節點CPU使用率低,而負載極高.登錄web節點服務器排查發現后段NFS服務器故障. 影響范圍: 網站看不到圖片了。 處理流程: 通過ssh登錄NFS服務…

醫療AI時代的生物醫學Go編程:高性能計算與精準醫療的案例分析(一)

摘要: 隨著高通量測序、醫學影像和電子病歷等生物醫學數據的爆炸式增長,對高效、可靠、可擴展的計算工具需求日益迫切。Go語言憑借其原生并發模型、卓越的性能、簡潔的語法和強大的標準庫,在生物醫學信息學領域展現出獨特優勢。本文以“生物醫學Go編程探析”為主題,通過三個…

針對 “TCP 連接建立階段” 的攻擊

針對 “TCP 連接建立階段” 的攻擊一、定義二、共性防御思路三、攻擊手段3.1、SYN 洪水攻擊&#xff08;SYN Flood&#xff09;3.2、Land 攻擊&#xff08;Land Attack&#xff09;一、定義 什么是針對 “TCP 連接建立階段” 的攻擊&#xff1f;核心特征是利用 TCP “三次握手…

聊一聊 單體分布式 和 微服務分布式

微服務 與 單體架構對比維度單體架構微服務架構??架構本質??一個單一的、功能齊全的應用程序一組??小型、獨立??的服務集合??開發??團隊工作在同一個代碼庫&#xff0c;易產生沖突。技術棧統一。每個服務可以由?? 獨立的小團隊 ??負責&#xff0c;允許使用??…

【C++八股文】計算機網絡篇

網絡協議核心知識點詳解 TCP頭部結構 TCP頭部包含多個關鍵字段&#xff0c;每個字段都有其特定作用&#xff1a; 16位源端口&#xff1a;標識發送方應用程序的端口號16位目的端口&#xff1a;標識接收方應用程序的端口號32位序號&#xff1a;保證數據包有序傳輸的唯一標識32…

小迪Web自用筆記7

游戲一般不走http https協議&#xff0c;一般的抓包工具抓不到。科來&#xff0c;這個工具是從網卡抓包。你一旦打怪數據就會多起來↓但不是很專業。可以抓到https。wep↑這個西東是全部協議都做流量包&#xff0c;你不知道他是從哪兒來的&#xff0c;他全都抓&#xff08;專業…

現代 Linux 發行版為何忽略Shell腳本的SUID位?

在現代Linux系統中&#xff0c;為Shell腳本設置 SUID&#xff08;Set User ID&#xff09; 權限位幾乎是無效的。這個看似簡單的現象背后&#xff0c;是Linux內核設計者們在安全與便利性之間做出的一個至關重要的歷史性抉擇。要徹底理解這一點&#xff0c;我們需要深入到內核層…

Qt節點編輯器設計與實現:動態編輯與任務流可視化(一)

文章目錄一、項目概述二、整體架構&#xff1a;模型-視圖分離的設計哲學1. 模型層&#xff1a;數據與業務邏輯的核心2. 視圖層&#xff1a;圖形渲染與用戶交互3. 交互層&#xff1a;連接模型與視圖的橋梁三、核心模塊解析1. 樣式管理系統&#xff1a;視覺表現的基石2. 圖形數據…

MySQL常見報錯分析及解決方案總結(4)---ERROR 1040(00000):Too many connections

報錯信息&#xff1a;ERROR 1040(00000):Too many comnections異常效果&#xff1a;原因分析&#xff1a;“ERROR 1040 (00000): Too many connections” 是 MySQL 數據庫最常見的連接數超限錯誤&#xff0c;本質是 “當前試圖連接數據庫的客戶端數量&#xff0c;超過了 MySQL …

GRPO(組相對策略優化):大模型強化學習的高效進化

本文由「大千AI助手」原創發布&#xff0c;專注用真話講AI&#xff0c;回歸技術本質。拒絕神話或妖魔化。搜索「大千AI助手」關注我&#xff0c;一起撕掉過度包裝&#xff0c;學習真實的AI技術&#xff01; ? 1. GRPO概述&#xff1a;重新定義大模型強化學習效率 GRPO&#x…

【Canvas與戳記】藍底黃面十六角Premium Quality戳記

【成圖】【代碼】<!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>藍底黃面十六角Premium Quality戳記 Draft1</title><style ty…

深度學習:洞察發展趨勢,展望未來藍圖

在科技飛速發展的當下&#xff0c;深度學習作為人工智能領域的璀璨明星&#xff0c;正以前所未有的速度重塑著各個行業的格局。從日常使用的智能語音助手&#xff0c;到醫療領域精準的疾病診斷&#xff0c;再到自動駕駛汽車對復雜路況的實時感知與決策&#xff0c;深度學習無處…