Unix C语言编写基于IO多路复用的小型并发服务器
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                Unix C语言编写基于IO多路复用的小型并发服务器
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                背景介紹
如果服務器要同時處理網絡上的套接字連接請求和本地的標準輸入命令請求,那么如果我們使用accept來接受連接請求,則無法處理標準輸入請求;類似地,如果在read中等待一個輸入請求,則無法處理網絡連接的請求。
所謂I/O多路復用機制,就是說通過一種機制,可以監視多個描述符,一旦某個描述符就緒(一般是讀就緒或者寫就緒),能夠通知程序進行相應的讀寫操作。但 select,poll,epoll本質上都是同步I/O,因為他們都需要在讀寫事件就緒后自己負責進行讀寫,也就是說這個讀寫過程是阻塞的,而還有一種情況是異步IO,異步I /O則無需自己負責進行讀寫,異步I/O的實現會負責把數據從內核拷貝到用戶空間。
使用select實現IO多路復用
我們可以使用select函數來實現等待一組描述符準備好讀。select函數處理類型為fd_set的集合,也叫做描述符集合。邏輯上,我們可以將描述符集合看成一個大小為n的位向量,每個位對應一個描述符。select函數是一個阻塞函數,即只有等到讀集合中至少有一個描述符可以讀時,就不會阻塞,開始處理請求了。
代碼如下:
#include "csapp.h"//此程序是使用基于 IO多路復用的并發服務器void echo(int connfd) {int n;char buf[MAXLINE];rio_t rio;rio_readinitb(&rio,connfd);//帶緩沖的讀取函數while((n=rio_readlineb(&rio,buf,MAXLINE))>0) {//向連接符寫入內容printf("server received %d bytes \n",n);rio_writen(connfd,buf,n);} }/*command是作為鍵盤輸入時執行的驅動動作*/ void command(void) {char buf[MAXLINE];printf("you input just now!\n");//從標準輸入中讀取輸入到buf中存儲if(!fgets(buf,MAXLINE,stdin))exit(0);//輸出buf中的數據printf("%s",buf); }//主程序 int main(int argc,char **argv) { //監聽符,連接符,端口號int listenfd,connfd,port;//套接字地址結構的大小socklen_t clientlen=sizeof(struct sockaddr_in);//新建套接字地址結構struct sockaddr_in clientaddr;//fd_set為描述符集合,此處定義了兩個read_set,ready_set描述符集合,分別是讀集合/準備好集合fd_set read_set,ready_set;//如果運行時參數小于2,則提示錯誤if(argc!=2) {fprintf(stderr,"usage :%s <port>\n",argv[0]);exit(0);}//將第二個參數轉化為整型端口號,args to integerport=atoi(argv[1]);//打開端口號,返回監聽描述符listenfd=open_listenfd(port);//清空讀集合FD_ZERO(&read_set);//將標準輸入加到讀集合FD_SET(STDIN_FILENO,&read_set);//將監聽描述符加到讀集合FD_SET(listenfd,&read_set);//服務器監聽處理主程序while(1) {//將讀集合賦值給準備好集合ready_set=read_set;//select函數會要求內核掛起進程,等待一個或多個IO事件發生后,才將控制返回給應用程序,就像在下面的示例一樣 select(listenfd+1,&ready_set,NULL,NULL,NULL);//有IO事件后,將判斷是來自從鍵盤上鍵入命令還是從客戶端發來的請求,分別給出不同的回應if(FD_ISSET(STDIN_FILENO,&ready_set))command();if(FD_ISSET(listenfd,&ready_set)) {connfd=accept(listenfd,(SA *)&clientaddr,&clientlen);printf("client connected!");//向連接符回送數據echo(connfd);//關閉連接符,釋放資源close(connfd);}} }測試部分
 
 
 
最后強調一下,這里是同步的IO問題,并非異步。
 
轉載于:https://my.oschina.net/zzw922cn/blog/493723
總結
以上是生活随笔為你收集整理的Unix C语言编写基于IO多路复用的小型并发服务器的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: input苹果6点击事件无效
- 下一篇: 一个小屁孩对父母说的经典话
