日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux TCP server系列(5)-select模式下的单进程server

發(fā)布時間:2023/12/10 linux 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux TCP server系列(5)-select模式下的单进程server 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目標(biāo):
?讓服務(wù)器退化為單進(jìn)程模式,但是利用select來提升性能

?

思路:
??? (1)服務(wù)器
?????? 傳統(tǒng)的單進(jìn)程服務(wù)器一旦accept了客戶端的TCP連接后,就轉(zhuǎn)入客戶請求的處理,處理完成后才能再一次的調(diào)用accept來接受下一個客戶端的TCP連接和請求。
?????? 為了更加提高單進(jìn)程server的性能,本程序使用select這種IO復(fù)用的模式,同時監(jiān)聽已經(jīng)連接的socket端口和正在監(jiān)聽的服務(wù)器listening端口,這樣一來,就可以大大提升sever處理并發(fā)請求的能力。
????? select的使用方式如下:
????? a)定義fd_set
???????? fd_set allset;
???????? select允許我們監(jiān)聽來自標(biāo)準(zhǔn)輸入,標(biāo)準(zhǔn)輸出,標(biāo)準(zhǔn)錯誤輸出的IO信號,本例中我們監(jiān)聽標(biāo)準(zhǔn)輸入IO信號集
????? b)注冊將要被監(jiān)聽的fd
?????? ?FD_SET(? listenfd, &allset )
??????? 通過FD_SET和 FD_CLR可以注冊和清除某個fd_set內(nèi)的fd項,使得在調(diào)用select的時候可以監(jiān)聽或者取消監(jiān)聽某個fd
???? c)如果IO信號到達(dá),識別并處理
??????? 通過FD_ISSET可以判斷select所監(jiān)聽的fd_set上的IO是否有狀態(tài)變化,一旦返回true,則可以對該fd進(jìn)行操作。
?
???? select使用事項及技巧:
?????? a)使用select時應(yīng)該注意,如果select有timeout設(shè)置,那么每次select之前都要再重新設(shè)置一下timeout的值,因為select成功的話會修改timeout的值。
?????? b)本例中,如果我們在某次select中捕獲到listenfd的IO狀態(tài)有變,也就是說有新的客戶端連接,我們不會馬上做客戶端的請求處理,而是把連接到的socket fd插入到select的監(jiān)聽集合中,然后繼續(xù)探測其他監(jiān)聽集有IO狀態(tài)變化(這里的其他監(jiān)聽集就是每個已經(jīng)連接的客戶端的socket fd的狀態(tài)),如果有變化則馬上處理client的請求。這樣做的好處是我們及時處理了已連接的客戶端的請求,而不是被新連接的客戶端的請求所搶占,反正舊客戶端被餓死的情況發(fā)生。
?????? c) 本例是在單進(jìn)程服務(wù)器上使用select,所以適合簡單客戶請求處理,也就是短連接的情況,如果需要長時間服務(wù)于多個客戶,可以使用fork加以輔助
?(2)客戶端無需改動

代碼:

server.cpp 1 #include<sys/types.h> 2 #include<sys/socket.h> 3 #include<strings.h> 4 #include<arpa/inet.h> 5 #include<unistd.h> 6 #include<stdlib.h> 7 #include<stdio.h> 8 #include<string.h> 9 #include<errno.h> 10 #include<signal.h> 11 #include<sys/wait.h> 12 #include<pthread.h> 13 14 #define LISTEN_PORT 84 15 16 void str_echo(int sockfd) // 服務(wù)器收到客戶端的消息后的響應(yīng) 17 { 18 ssize_t n; 19 char line[512]; 20 21 printf("ready to read/n"); 22 23 while( (n=read(sockfd,line,512))>0 ) 24 { 25 line[n]='/0'; 26 printf("Client Diary: %s/n",line); 27 28 char msgBack[512]; 29 snprintf(msgBack,sizeof(msgBack),"recv: %s/n",line); 30 write(sockfd,msgBack,strlen(msgBack)); 31 bzero(&line,sizeof(line)); 32 } 33 34 printf("end read/n"); 35 36 } 37 38 void sig_child(int signo) //父進(jìn)程對子進(jìn)程結(jié)束的信號處理 39 { 40 pid_t pid; 41 int stat; 42 43 while( (pid=waitpid(-1,&stat,WNOHANG))>0) 44 printf("child %d terminated/n",pid); 45 46 return; 47 } 48 49 50 int main(int argc, char **argv) 51 { 52 53 int listenfd, connfd; 54 pid_t childpid; 55 socklen_t chilen; 56 57 struct sockaddr_in chiaddr,servaddr; 58 59 //values for select 60 int i,maxi,maxfd,sockfd; 61 int nready,client[FD_SETSIZE]; 62 ssize_t n; 63 fd_set rset,allset; 64 //values for select 65 66 listenfd=socket(AF_INET,SOCK_STREAM,0); 67 if(listenfd==-1) 68 { 69 printf("socket established error: %s/n",(char*)strerror(errno)); 70 } 71 72 bzero(&servaddr,sizeof(servaddr)); 73 servaddr.sin_family=AF_INET; 74 servaddr.sin_addr.s_addr=htonl(INADDR_ANY); 75 servaddr.sin_port=htons(LISTEN_PORT); 76 77 int bindc=bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); 78 if(bindc==-1) 79 { 80 printf("bind error: %s/n",strerror(errno)); 81 } 82 83 listen(listenfd,SOMAXCONN); //limit是SOMAXCONN 84 85 //initial "select" elements 86 maxfd=listenfd; //新增listenfd,所以更新當(dāng)前的最大fd 87 maxi=-1; 88 for(i=0;i<FD_SETSIZE;i++) 89 client[i] = -1; 90 FD_ZERO(&allset); 91 FD_SET(listenfd,&allset); 92 //initial "select" elements 93 94 signal(SIGCHLD,sig_child); 95 for(;;) 96 { 97 rset=allset; //rset和allset的搭配使得新加入的fd要等到下次select才會被監(jiān)聽 98 nready=select(maxfd+1,&rset,NULL,NULL,NULL); //一開始select監(jiān)聽的是監(jiān)聽口 99 //如果有timeout設(shè)置,那么每次select之前都要再重新設(shè)置一下timeout的值 100 //因為select會修改timeout的值。 101 102 if(FD_ISSET(listenfd,&rset)) 103 { 104 chilen=sizeof(chiaddr); 105 106 connfd=accept(listenfd,(struct sockaddr*)&chiaddr,&chilen); 107 //阻塞在accept,直到三次握手成功了才返回 108 if(connfd==-1) 109 printf("accept client error: %s/n",strerror(errno)); 110 else 111 printf("client connected/n"); 112 113 for(i=0;i<FD_SETSIZE;i++) 114 { 115 if (client[i]<0) 116 { 117 client[i]=connfd; //找一個最小的插進(jìn)入,并且緩存在client中,這樣就不需要遍歷所有fd,包括為0位的,來查看是否ISSET 118 break; 119 } 120 } 121 if(i==FD_SETSIZE) 122 { 123 printf("too many clients/n"); 124 exit(0); 125 } 126 FD_SET(connfd,&allset); //新加入的描述符,還沒判斷是否可以或者寫,所以后面使用rset而不是allset 127 128 if(connfd>maxfd) //maxfd是為了下次select,作為參數(shù)使用 129 maxfd=connfd; 130 if(i>maxi) //maxi是為了減少遍歷所監(jiān)聽fd的次數(shù) 131 maxi=i; 132 if(--nready<=0) //nready用來輔助計數(shù),這樣就不要遍歷整個client數(shù)組 133 continue; 134 } 135 136 137 for(i=0;i<=maxi;i++) 138 { 139 if( (sockfd=client[i]) <0) 140 continue; 141 if(FD_ISSET(sockfd,&rset)) 142 { 143 //單進(jìn)程的環(huán)境下,不可以阻塞在這里,可以選擇非阻塞,線程,超時.也就無法防范拒絕服務(wù)的攻擊 144 //比較適合短連接的情況 145 146 //單進(jìn)程不使用fork的情況! 147 //test fork 148 // if((childpid=fork())==0) 149 { 150 close(listenfd); 151 printf("client from %s/n",inet_ntoa(chiaddr.sin_addr)); 152 str_echo(connfd); 153 close(connfd); 154 155 exit(0); 156 } 157 // else if (childpid<0) 158 // printf("fork error: %s/n",strerror(errno)); 159 close(connfd); 160 //test fork 161 162 FD_CLR(sockfd,&allset); //清除,表示已被處理 163 client[i]=-1; 164 165 printf("can read : %d,%d,%d/n",i,sockfd,nready); 166 if(--nready<=0) //nready用來輔助計數(shù),這樣就不要遍歷整個client數(shù)組 167 break; 168 } 169 } 170 } 171 }

  


作者: Aga.J
出處: http://www.cnblogs.com/aga-j
本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。

總結(jié)

以上是生活随笔為你收集整理的Linux TCP server系列(5)-select模式下的单进程server的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美日韩 一区二区三区 | 波多野吉衣av | 色综合天天综合综合国产 | 黄色网在线免费观看 | 国产日韩一区二区在线观看 | 国产剧情av在线 | 欧美四级在线观看 | 国产亚洲av综合人人澡精品 | 国产伊人精品 | 亚洲精品乱码久久久久久按摩观 | 一区二区网站 | 久热精品在线视频 | 美女屁股网站 | 日韩男女啪啪 | 日本高清视频在线观看 | 久久久无码18禁高潮喷水 | 国产三级精品三级在线观看 | 国产一区二区在线播放 | 日本r级电影在线观看 | 国产在成人精品线拍偷自揄拍 | 久久一视频 | 最好看十大无码av | 久久久精品中文字幕麻豆发布 | 欧美8888 | 亚洲 欧美 自拍偷拍 | 打美女白嫩屁屁网站 | av免费精品 | 美女131爽爽爽做爰视频 | 成人在线观看网址 | 久久久久久国产免费a片 | 国产全肉乱妇杂乱视频 | 日韩一级在线观看 | 污污视频在线观看网站 | 国产成人在线精品 | 久操久操 | 最新天堂在线视频 | 国产一区二区三区在线免费 | 久久免费久久 | 亚洲一区二区影院 | 9久久精品 | 欧美爱爱免费视频 | 久久久久极品 | 大陆av片| 黄色大片儿.| 精品国产亚洲一区二区麻豆 | 天天想你免费观看完整版高清电影 | 伊人久久久久久久久久久 | 欧美丰满老熟妇aaaa片 | 99蜜桃臀久久久欧美精品网站 | 国产亚洲综合在线 | 天天视频黄色 | 亚洲av无码日韩精品影片 | 国产91在线观看丝袜 | 五月天综合视频 | 国产片高清在线观看 | 中国黄色三级视频 | 男女一起插插插 | 草莓巧克力香氛动漫的观看方法 | 1000部啪啪 | 久久久久久久久久久影视 | 成人免费高清在线观看 | 日韩一区二区三区免费 | 日韩女优在线 | 欧美日韩一级二级三级 | 绿帽视频| 欧美三级影院 | 国产福利一区视频 | 亚洲视频一二区 | 久久精品久久久 | 天堂v在线观看 | 少女情窦初开的第4集在线观看 | 久久h| 精品国产人妻一区二区三区 | 九色蝌蚪9l视频蝌蚪9l视频 | 亚洲av无码一区二区三区四区 | 草草影院第一页 | 亚洲视频精品在线 | 96精品在线 | www九色| 国产视频久久久 | 色综合天天操 | www视频在线观看 | 91麻豆精品一二三区在线 | 台湾a级艳片潘金莲 | 日韩精品一区三区 | 亚洲第九页 | 成人免费自拍视频 | 成人精品视频在线观看 | 国产电影一区在线观看 | 最近中文字幕在线观看 | 国产一区网 | 天天爽天天射 | 91成人高清 | 毛片aaaaaa| 成人欧美一区二区三区小说 | 爽妇网国产精品 | 成年人视频网 | 人人干网站 | 91精品在线观看视频 |