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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

服务器之poll

發(fā)布時(shí)間:2023/11/30 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 服务器之poll 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

poll服務(wù)器方法采用將監(jiān)聽端口用數(shù)組存放起來,這樣就不需要輪詢的監(jiān)聽整個(gè)文件描述符了

#include <poll.h> int poll(struct pollfd *fds, nfds_t nfds, int timeout);struct pollfd {int fd; /* 文件描述符 */short events; /* 監(jiān)控的事件 */short revents; /* 監(jiān)控事件中滿足條件返回的事件 */};POLLIN 普通或帶外優(yōu)先數(shù)據(jù)可讀,即POLLRDNORM | POLLRDBANDPOLLRDNORM 數(shù)據(jù)可讀POLLRDBAND 優(yōu)先級帶數(shù)據(jù)可讀POLLPRI 高優(yōu)先級可讀數(shù)據(jù)POLLOUT 普通或帶外數(shù)據(jù)可寫POLLWRNORM 數(shù)據(jù)可寫POLLWRBAND 優(yōu)先級帶數(shù)據(jù)可寫POLLERR 發(fā)生錯(cuò)誤POLLHUP 發(fā)生掛起POLLNVAL 描述字不是一個(gè)打開的文件nfds 監(jiān)控?cái)?shù)組中有多少文件描述符需要被監(jiān)控timeout 毫秒級等待-1:阻塞等,#define INFTIM -1 Linux中沒有定義此宏0:立即返回,不阻塞進(jìn)程>0:等待指定毫秒數(shù),如當(dāng)前系統(tǒng)時(shí)間精度不夠毫秒,向上取值

如果不再監(jiān)控某個(gè)文件描述符時(shí),可以把pollfd中,fd設(shè)置為-1poll不再監(jiān)控此pollfd,下次返回時(shí),把revents設(shè)置為0

?

/* server.c */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <netinet/in.h> #include <arpa/inet.h> #include <poll.h> #include <errno.h> #include "wrap.h"#define MAXLINE 80 #define SERV_PORT 6666 #define OPEN_MAX 1024int main(int argc, char *argv[]) {int i, j, maxi, listenfd, connfd, sockfd;int nready;ssize_t n;char buf[MAXLINE], str[INET_ADDRSTRLEN];socklen_t clilen;struct pollfd client[OPEN_MAX];struct sockaddr_in cliaddr, servaddr;listenfd = Socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));Listen(listenfd, 20);client[0].fd = listenfd;client[0].events = POLLRDNORM; /* listenfd監(jiān)聽普通讀事件 */for (i = 1; i < OPEN_MAX; i++)client[i].fd = -1; /* 用-1初始化client[]里剩下元素 */maxi = 0; /* client[]數(shù)組有效元素中最大元素下標(biāo) */for ( ; ; ) {nready = poll(client, maxi+1, -1); /* 阻塞 */if (client[0].revents & POLLRDNORM) { /* 有客戶端鏈接請求 */clilen = sizeof(cliaddr);connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);printf("received from %s at PORT %d\n",inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),ntohs(cliaddr.sin_port));for (i = 1; i < OPEN_MAX; i++) {if (client[i].fd < 0) {client[i].fd = connfd; /* 找到client[]中空閑的位置,存放accept返回的connfd */break;}}if (i == OPEN_MAX)perr_exit("too many clients");client[i].events = POLLRDNORM; /* 設(shè)置剛剛返回的connfd,監(jiān)控讀事件 */if (i > maxi)maxi = i; /* 更新client[]中最大元素下標(biāo) */if (--nready <= 0)continue; /* 沒有更多就緒事件時(shí),繼續(xù)回到poll阻塞 */}for (i = 1; i <= maxi; i++) { /* 檢測client[] */if ((sockfd = client[i].fd) < 0)continue;if (client[i].revents & (POLLRDNORM | POLLERR)) {if ((n = Read(sockfd, buf, MAXLINE)) < 0) {if (errno == ECONNRESET) { /* 當(dāng)收到 RST標(biāo)志時(shí) *//* connection reset by client */printf("client[%d] aborted connection\n", i);Close(sockfd);client[i].fd = -1;} else {perr_exit("read error");}} else if (n == 0) {/* connection closed by client */printf("client[%d] closed connection\n", i);Close(sockfd);client[i].fd = -1;} else {for (j = 0; j < n; j++)buf[j] = toupper(buf[j]);Writen(sockfd, buf, n);}if (--nready <= 0)break; /* no more readable descriptors */}}}return 0; }

client

/* client.c */ #include <stdio.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #include "wrap.h"#define MAXLINE 80 #define SERV_PORT 6666int main(int argc, char *argv[]) {struct sockaddr_in servaddr;char buf[MAXLINE];int sockfd, n;sockfd = Socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);servaddr.sin_port = htons(SERV_PORT);Connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));while (fgets(buf, MAXLINE, stdin) != NULL) {Write(sockfd, buf, strlen(buf));n = Read(sockfd, buf, MAXLINE);if (n == 0)printf("the other side has been closed.\n");elseWrite(STDOUT_FILENO, buf, n);}Close(sockfd);return 0; }

同樣的包含了wrap.c和wrap.h的文件,放在錯(cuò)誤分析的那個(gè)博客中

#include <poll.h>

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

??? struct pollfd {

??????? int fd; /* 文件描述符 */

??????? short events; /* 監(jiān)控的事件 */

??????? short revents; /* 監(jiān)控事件中滿足條件返回的事件 */

??? };

??? POLLIN??????? 普通或帶外優(yōu)先數(shù)據(jù)可讀,POLLRDNORM | POLLRDBAND

??? POLLRDNORM????? 數(shù)據(jù)可讀

??? POLLRDBAND????? 優(yōu)先級帶數(shù)據(jù)可讀

??? POLLPRI ??????? 高優(yōu)先級可讀數(shù)據(jù)

??? POLLOUT?? ??? 普通或帶外數(shù)據(jù)可寫

??? POLLWRNORM????? 數(shù)據(jù)可寫

??? POLLWRBAND????? 優(yōu)先級帶數(shù)據(jù)可寫

??? POLLERR ????? 發(fā)生錯(cuò)誤

??? POLLHUP ??????? 發(fā)生掛起

??? POLLNVAL ?????? 描述字不是一個(gè)打開的文件

?

??? nfds ?????????? 監(jiān)控?cái)?shù)組中有多少文件描述符需要被監(jiān)控

?

??? timeout ??????? 毫秒級等待

??????? -1:阻塞等,#define INFTIM -1 ?????????????? Linux中沒有定義此宏

??????? 0:立即返回,不阻塞進(jìn)程

??????? >0:等待指定毫秒數(shù),如當(dāng)前系統(tǒng)時(shí)間精度不夠毫秒,向上取值

?

轉(zhuǎn)載于:https://www.cnblogs.com/wanghao-boke/p/11409506.html

總結(jié)

以上是生活随笔為你收集整理的服务器之poll的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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