網絡編程(8.15)io模型,IO多路復用(select,poll)

1.使用select函數實現IO多路復用

使用select函數實現IO多路復用的服務器:

#include<stdio.h>
#include<head.h>
#include<netinet/in.h>
#include<sys/select.h>
#include<arpa/inet.h>
#define PROT 1112
#define IP "192.168.125.232"
int main(int argc, const char *argv[])
{//創建流式套接字int sfd=socket(AF_INET,SOCK_STREAM,0);if(sfd<0){   ERR_MSG("socket");return -1; }   printf("sfd=%d\n",sfd);//設置允許端口被快速復用int reuse=1;if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0){   ERR_MSG("setsockopt");return -1; }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            printf("允許端口快速復用成功\n");//綁定服務器的IP和端口--->必須綁定struct sockaddr_in sin;sin.sin_family      = AF_INET;//必須填AF_INETsin.sin_port        = htons(PROT);//端口號:1024~49151sin.sin_addr.s_addr = inet_addr(IP);//本機IPif(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0){   ERR_MSG("bind");return -1; }   printf("綁定成功\n");//將套接字設置為被動監聽狀態if(listen(sfd,128)<0){   ERR_MSG("listen");return -1; }   printf("被動監聽狀態設置成功\n");//創建一個讀集合fd_set readfds,tempfds;//fd_set本質是一個結構體,成員是一個long類型的數組//集合目的是為了存儲讓內核監測的文件描述符,不初始化有可能隨機到有效的但不需要監測的文件描述符//需要將集合初始化為無意義的文件描述符FD_ZERO(&readfds);FD_ZERO(&tempfds);//將需要的文件描述符添加到讀集合中FD_SET(0,&readfds);FD_SET(sfd,&readfds);int s_res=-1;int nfd=-1;int maxfd=sfd;char buf[128]="";ssize_t res=0;struct sockaddr_in cin;//存儲客戶端地址信息socklen_t addrlen = sizeof(cin);struct sockaddr_in saveCin[1024];while(1){   tempfds = readfds;//調用io多路復用函數 select()s_res = select(maxfd+1,&tempfds,NULL,NULL,NULL);if(s_res < 0){ERR_MSG("select");return -1; }else if(0 == s_res){printf("timeout...\n");break;}printf("__%d__\n",__LINE__);//能運行到當前位置,代表集合中有文件描述符準備就緒//此時集合中路會只剩下觸發事件的文件描述符//例如://當0號文件描述符觸發事件,則集合中只剩下0//當sfd文件描述符觸發事件,則集合中只剩下sfd//當0和sfd同時觸發,集合中剩下0和sfd//判斷哪個文件描述符準備就緒,走對應處理函數//判斷集合中剩下哪個文件描述符,代表哪個文件描述符準備就緒//判斷nfd是否在集合中,若不在集合中則走recv函數for(int i=0;i<=maxfd;i++){if(FD_ISSET(i,&tempfds)==0)//判斷i是否在集合中,不在進入下一個循環continue;if(0 == i){printf("觸發鍵盤輸入事件\n");fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]=0;printf(": %s\n",buf);}else if(sfd == i){printf("觸發客戶端連接事件\n");nfd=accept(sfd,(struct sockaddr*)&cin,&addrlen);if(nfd<0){ERR_MSG("accept");return -1; }printf("[%s:%d]nfd=%d,客戶端連接成功\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),nfd);saveCin[nfd]=cin;//將nfd添加到集合中FD_SET(nfd,&readfds);//更新maxfdmaxfd = maxfd>nfd ? maxfd : nfd;    }else{printf("客戶端交互\n");//接收數據bzero(buf,sizeof(buf));res=recv(i,buf,sizeof(buf),0);if(res<0){ERR_MSG("recv");return -1; }else if(0==res){printf("[%s:%d]nfd=%d 客戶端下線\n",inet_ntoa(saveCin[i].sin_addr),ntohs(saveCin[i].sin_port),i);//關閉下線客戶端的文件描述符close(i);//將下線客戶端的文件描述符從集合中刪除FD_CLR(i,&readfds);//更新maxfd//從目前記錄的最大fd開始判斷是否在集合中,存在為最大,//不存在往前開始判斷前一個在不在,直到判斷到在的為最大while(FD_ISSET(maxfd,&readfds)==0&&maxfd-->=0);/* int j=maxfd; for(;j>=0;j--){if(FD_ISSET(maxfd,&readfds))break;maxfd=j;}*/continue;}printf("nfd=%d : %s\n",i,buf);//發送數據strcat(buf,"*_*");if(send(nfd,buf,sizeof(buf),0)<0){ERR_MSG("send");return -1; }printf("發送成功\n");}}}   //關閉所有文件描述符close(sfd);return 0;
}                

使用select函數實現IO多路復用的客戶端:

#include<stdio.h>
#include<head.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/select.h>
#define PROT 1112//服務器綁定的端口
#define IP "192.168.125.232"//服務器綁定的IP端口
int main(int argc, const char *argv[])
{//創建流式套接字int cfd=socket(AF_INET,SOCK_STREAM,0);if(cfd<0){   ERR_MSG("socket");return -1; }   printf("cfd=%d\n",cfd);//綁定客戶端的IP和端口--->非必須綁定//連接服務器//先填充服務器的地址信息結構體,真實地址信息結構體根據地址族制定struct sockaddr_in sin;sin.sin_family   = AF_INET;sin.sin_port     = htons(PROT);//服務器綁定的端口號sin.sin_addr.s_addr     = inet_addr(IP);//服務器綁定的本機IP//連接服務器if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin))<0){   ERR_MSG("connect");return -1; }   printf("連接服務器成功\n");char buf[128]="";ssize_t res=0;int s_res=-1;//創建讀集合fd_set readfds,tempfds;FD_ZERO(&readfds);FD_ZERO(&tempfds);FD_SET(0,&readfds);FD_SET(cfd,&readfds);while(1){   tempfds=readfds;s_res=select(cfd+1,&tempfds,NULL,NULL,NULL);if(s_res<0){ERR_MSG("select");return -1; }else if(0==s_res){printf("time out...\n");break;}printf("__%d__\n",__LINE__);//能運行到這代表集合中有文件描述符準備就緒//判斷哪個文件描述符準備就緒,運行對應函數if(FD_ISSET(0,&tempfds)){printf("觸發鍵盤輸入事件\n");bzero(buf,sizeof(buf));fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]=0;//發送數據if(send(cfd,buf,sizeof(buf),0)<0){ERR_MSG("send");return -1; }printf("發送成功\n");}else if(FD_ISSET(cfd,&tempfds)){printf("觸發服務器交互\n");bzero(buf,sizeof(buf));//接收數據res=recv(cfd,buf,sizeof(buf),0);if(res<0){                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      ERR_MSG("recv");return -1; }else if(0==res){printf("[%s:%d]cfd=%d 服務器掉線\n",IP,PROT,cfd);break;}printf("[%s:%d]cfd=%d : %s\n",IP,PROT,cfd,buf);}}   //關閉所有文件描述符close(cfd);return 0;
} 

?使用poll函數實現IO多路復用的客戶端:

#include<stdio.h>
#include<head.h>
#include<poll.h>
#define PROT 1112//服務器綁定的端口
#define IP "192.168.125.232"//服務器綁定的IP端口
int main(int argc, const char *argv[])
{//創建流式套接字int cfd=socket(AF_INET,SOCK_STREAM,0);if(cfd<0){ERR_MSG("socket");return -1;}printf("cfd=%d\n",cfd);//綁定客戶端的IP和端口--->非必須綁定//連接服務器//先填充服務器的地址信息結構體,真實地址信息結構體根據地址族制定struct sockaddr_in sin;sin.sin_family   = AF_INET;sin.sin_port     = htons(PROT);//服務器綁定的端口號sin.sin_addr.s_addr     = inet_addr(IP);//服務器綁定的本機IP//連接服務器if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin))<0){ERR_MSG("connect");return -1;}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              printf("連接服務器成功\n");char buf[128]="";ssize_t res=0;int p_res=-1;//定義集合struct pollfd fds[2];//將需要監測的文件描述符添加到集合fds[0].fd=0;//制定監測0號文件描述符fds[0].events=POLLIN;fds[1].fd=cfd;fds[1].events=POLLIN;while(1){p_res=poll(fds,2,-1);if(p_res<0){ERR_MSG("poll");return -1;}else if(0==p_res){printf("time out...\n");break;}//能運行到這代表集合中有文件描述符準備就緒//判斷哪個文件描述符準備就緒,運行對應處理函數//判斷集合中的每個文件描述符中是否有pollin//從revents中將代表pollin的那一位單獨提取出來,判斷是1還是0if((fds[0].revents&POLLIN)!=0){printf("觸發鍵盤輸入事件\n");bzero(buf,sizeof(buf));fgets(buf,sizeof(buf),stdin);buf[strlen(buf)-1]=0;//發送數據if(send(cfd,buf,sizeof(buf),0)<0){ERR_MSG("send");return -1;}printf("發送成功\n");}if(fds[1].revents&POLLIN){printf("觸發服務器交互\n");bzero(buf,sizeof(buf));//接收數據res=recv(cfd,buf,sizeof(buf),0);if(res<0){ERR_MSG("recv");return -1;}else if(0==res){printf("[%s:%d]cfd=%d 服務器掉線\n",IP,PROT,cfd);break;}printf("[%s:%d]cfd=%d : %s\n",IP,PROT,cfd,buf);}}//關閉所有文件描述符close(cfd);return 0;
}

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

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

相關文章

29 | 廣州美食店鋪數據分析

廣州美食店鋪數據分析 一、數據分析項目MVP加/價值主張宣言 隨著經濟的快速發展以及新媒體的興起,美食攻略、美食探店等一系列東西進入大眾的眼球,而人們也會在各大平臺中查找美食推薦,因此本項目做的美食店鋪數據分析也是帶有可行性的。首先通過對廣東省的各市美食店鋪數量…

對話即數據分析,網易數帆ChatBI做到了

大數據產業創新服務媒體 ——聚焦數據 改變商業 在當今數字化快速發展的時代&#xff0c;數據已經成為業務經營與管理決策的核心驅要素。無論是跨國大企業還是新興創業公司&#xff0c;正確、迅速地洞察數據已經變得至關重要。然而&#xff0c;傳統的BI工具往往對用戶有一定的…

初步認識OSI/TCP/IP一(第三十八課)

1 初始OSI模型 OSI參考模型(Open Systems Interconnection Reference Model)是一個由國際標準化組織(ISO)和國際電報電話咨詢委員會(CCITT)聯合制定的網絡通信協議規范,它將網絡通信分為七個不同的層次,每個層次負責不同的功能和任務。 2 網絡功能 數據通信、資源共享…

MTK Android非常用分辨率修改充電動畫

非標準分辨率的屏,配置MTK Android的關機充電動畫. 環境 芯片 MTK 系統 Android 服務器 ubuntu 屏幕分辨率356*400,不是常見的分辨率. 原始充電動畫顯示異常,畫面扭曲. 方法 確定使用的圖片 vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo 這個目錄下…

springboot多模塊打包方式

明確子父模塊結構 父目錄是帶modules 大致結構如下&#xff1a; <modules><module>ruoyi-admin</module><module>ruoyi-framework</module><module>ruoyi-system</module><module>ruoyi-quartz</module><module>…

htmlCSS-----高級選擇器

目錄 前言 偽類選擇器 狀態類 結構類 偽元素選擇器 屬性選擇器 前言 前面我們學習了CSS中的相關選擇器&#xff08;鏈接html&CSS-----CSS選擇器&#xff08;上&#xff09;_灰勒塔德的博客-CSDN博客 html&CSS-----CSS選擇器&#xff08;下&#xff09;_灰勒塔…

計算機視覺中的Transformer

幾十年來&#xff0c;理論物理學家一直在努力提出一個宏大的統一理論。通過統一&#xff0c;指的是將被認為是完全不同的兩個或多個想法結合起來&#xff0c;將它們的不同方面證明為同一基礎現象。一個例子是在19世紀之前&#xff0c;電和磁被看作是無關的現象&#xff0c;但電…

基于java的汽車改裝方案網站設計與實現

摘要 本文主要講述了基于SpringBootMySql開發技術開發的汽車改裝方案網站的設計與實現。這里的汽車改裝方案網站是通過一個平臺使所有的汽車愛好者們可以不用出門就可以體驗到專業的汽車改裝方案設計服務。現實生活中如果需要進行汽車改裝的方案設計&#xff0c;往往要跑很多次…

【大數據之Kafka】三、Kafka生產者之消息發送流程及同步異步發送API

將外部傳送給過來的數據發送到kafka集群。 1 發送原理 &#xff08;1&#xff09;創建main()線程&#xff0c;創建producer對象&#xff0c;調用send方法&#xff0c;經過攔截器&#xff08;可選&#xff09;、序列化器、分區器。 &#xff08;2&#xff09;分區器將數據發送…

【Android Framework (十二) 】- 智能硬件設備開發

文章目錄 前言智能硬件的定義與應用智能硬件產品開發流程智能硬件開發所涉及的技術體系概述關于主板選型主板CPU芯片的選擇關于串口通信 總結 前言 針對我過往工作經歷&#xff0c;曾在一家智能科技任職Android開發工程師&#xff0c;簡單介紹下關于任職期間接觸和開發過的一些…

DDPM: Denoising Diffusion Probabilistic Models

DDPM: Denoising Diffusion Probabilistic Models 去噪擴散模型前向過程-加噪聲反向過程-去噪聲 去噪擴散模型 論文題目&#xff1a;Denoising Diffusion Probabilistic Models (DDPM) 論文來源&#xff1a;NIPS, 2020 論文地址&#xff1a;https://arxiv.org/abs/2006.11239 論…

RH850從0搭建Autosar開發環境【24】- Davinci Configurator之DEM模塊配置詳解(上)

DEM模塊配置詳解 - 上 一、Autosar中DEM模塊簡介1.DEM對其他模塊的依賴2.DEM模塊架構2.1 DEM模塊Dem Satellite(s) 和Master2.2 診斷事件處理2.2.1 基于計數器的算法2.2.2 基于時間的算法三、配置錯誤項處理3.1 容器DemEventParameter3.2 容器DemOperationCycleRef3.3 容器DemO…

13.3 目標檢測和邊界框

錨框的計算公式 假設原圖的高為H,寬為W 詳細公式推導 以同一個像素點為錨框&#xff0c;可以生成 (n個縮放 m個寬高比 -1 )個錨框 錨框的作用&#xff1a; 不用直接去預測真實框的四個坐標&#xff0c;而是&#xff1a; 1.先生成多個錨框。 2.預測每個錨框里是否含有要預測…

C++:哈希表——模擬散列表

模擬散列表 維護一個集合&#xff0c;支持如下幾種操作&#xff1a; 1.“I x”&#xff0c;插入一個數x 2.“Q x”&#xff0c;詢問數x是否在集合中出現過 現在要進行N次操作&#xff0c;對于每個詢問操作輸出對應的結果 輸入格式 第一行包含整數N&#xff0c;表示操作數量 …

【Linux】【驅動】雜項設備驅動

【Linux】【驅動】雜項設備驅動 Linux三大設備驅動1. 我們這節課要講的雜項設備驅動是屬于我們這三大設備驅動里面的哪個呢?2.雜項設備除了比字符設備代碼簡單&#xff0c;還有別的區別嗎?3.主設備號和次設備號是什么? 掛載驅動 雜項設備驅動是字符設備驅動的一種&#xff0…

小程序制作教程:從零開始搭建企業小程序

在如今的數字化時代&#xff0c;企業介紹小程序成為了企業展示與推廣的重要工具。通過企業介紹小程序&#xff0c;企業可以向用戶展示自己的品牌形象、產品服務以及企業文化等內容&#xff0c;進而提高用戶對企業的認知度和信任度。本文將介紹如何從零開始搭建一個企業介紹小程…

Linux常用命令詳細大全

目錄 1、查看目錄與文件&#xff1a;ls2、切換目錄&#xff1a;cd3、顯示當前目錄&#xff1a;pwd4、創建空文件&#xff1a;touch5、創建目錄&#xff1a;mkdir6、查看文件內容&#xff1a;cat7、分頁查看文件內容&#xff1a;more8、查看文件尾內容&#xff1a;tail9、拷貝&a…

小程序 vant 項目記錄總結 使用 scss 分享 訂閱消息 wxs 分包 echarts圖表 canvas getCurrentPages頁面棧

小程序 vant vant 下載 npm init -ynpm i vant/weapp -S --production修改 app.json 將 app.json 中的 “style”: “v2” 去除 修改 project.config.json {..."setting": {..."packNpmManually": true,"packNpmRelationList": [{"p…

域名配置HTTPS

一、注冊域名 這個可以在各大平臺注冊&#xff0c;具體看一下就會注冊了&#xff0c;自己挑選一個自己喜歡的域名。 步驟一般也就是先實名&#xff0c;實名成功了才能注冊域名。 二、辦理SSL證書 這里使用的是阿里云的SSL免費證書 1、申請證書 二、填寫申請 三、域名綁定生…

公司電腦三維圖紙加密、機械圖擋加密軟件

機械圖紙加密軟件的問世&#xff0c;讓很多的網絡公司都大受其帶來的工作中的便利。在安裝了機械圖紙加密軟件后&#xff0c;不僅可以很好的管理員工在工作時的上網娛樂&#xff0c;在對整個公司員工的工作效率上也有著明顯的提高&#xff0c;那么對于機械圖紙加密軟件的具體特…