麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 服務器 > Linux服務器 > 正文

Linux IO多路復用之epoll網絡編程

2024-09-05 23:05:29
字體:
來源:轉載
供稿:網友

前言

本章節是用基本的Linux基本函數加上epoll調用編寫一個完整的服務器和客戶端例子,可在Linux上運行,客戶端和服務端的功能如下:

  • 客戶端從標準輸入讀入一行,發送到服務端
  • 服務端從網絡讀取一行,然后輸出到客戶端
  • 客戶端收到服務端的響應,輸出這一行到標準輸出

服務端

代碼如下:

#include <unistd.h>#include <sys/types.h>    /* basic system data types */#include <sys/socket.h>   /* basic socket definitions */#include <netinet/in.h>   /* sockaddr_in{} and other Internet defns */#include <arpa/inet.h>    /* inet(3) functions */#include <sys/epoll.h> /* epoll function */#include <fcntl.h>   /* nonblocking */#include <sys/resource.h> /*setrlimit */#include <stdlib.h>#include <errno.h>#include <stdio.h>#include <string.h>#define MAXEPOLLSIZE 10000#define MAXLINE 10240int handle(int connfd);int setnonblocking(int sockfd){  if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1) {    return -1;  }  return 0;}int main(int argc, char **argv){  int servPort = 6888;  int listenq = 1024;  int listenfd, connfd, kdpfd, nfds, n, nread, curfds,acceptCount = 0;  struct sockaddr_in servaddr, cliaddr;  socklen_t socklen = sizeof(struct sockaddr_in);  struct epoll_event ev;  struct epoll_event events[MAXEPOLLSIZE];  struct rlimit rt;  char buf[MAXLINE];  /* 設置每個進程允許打開的最大文件數 */  rt.rlim_max = rt.rlim_cur = MAXEPOLLSIZE;  if (setrlimit(RLIMIT_NOFILE, &rt) == -1)   {    perror("setrlimit error");    return -1;  }  bzero(&servaddr, sizeof(servaddr));  servaddr.sin_family = AF_INET;   servaddr.sin_addr.s_addr = htonl (INADDR_ANY);  servaddr.sin_port = htons (servPort);  listenfd = socket(AF_INET, SOCK_STREAM, 0);   if (listenfd == -1) {    perror("can't create socket file");    return -1;  }  int opt = 1;  setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));  if (setnonblocking(listenfd) < 0) {    perror("setnonblock error");  }  if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) == -1)   {    perror("bind error");    return -1;  }   if (listen(listenfd, listenq) == -1)   {    perror("listen error");    return -1;  }  /* 創建 epoll 句柄,把監聽 socket 加入到 epoll 集合里 */  kdpfd = epoll_create(MAXEPOLLSIZE);  ev.events = EPOLLIN | EPOLLET;  ev.data.fd = listenfd;  if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, listenfd, &ev) < 0)   {    fprintf(stderr, "epoll set insertion error: fd=%d/n", listenfd);    return -1;  }  curfds = 1;  printf("epollserver startup,port %d, max connection is %d, backlog is %d/n", servPort, MAXEPOLLSIZE, listenq);  for (;;) {    /* 等待有事件發生 */    nfds = epoll_wait(kdpfd, events, curfds, -1);    if (nfds == -1)    {      perror("epoll_wait");      continue;    }    /* 處理所有事件 */    for (n = 0; n < nfds; ++n)    {      if (events[n].data.fd == listenfd)       {        connfd = accept(listenfd, (struct sockaddr *)&cliaddr,&socklen);        if (connfd < 0)         {          perror("accept error");          continue;        }        sprintf(buf, "accept form %s:%d/n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port);        printf("%d:%s", ++acceptCount, buf);        if (curfds >= MAXEPOLLSIZE) {          fprintf(stderr, "too many connection, more than %d/n", MAXEPOLLSIZE);          close(connfd);          continue;        }         if (setnonblocking(connfd) < 0) {          perror("setnonblocking error");        }        ev.events = EPOLLIN | EPOLLET;        ev.data.fd = connfd;        if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, connfd, &ev) < 0)        {          fprintf(stderr, "add socket '%d' to epoll failed: %s/n", connfd, strerror(errno));          return -1;        }        curfds++;        continue;      }       // 處理客戶端請求      if (handle(events[n].data.fd) < 0) {        epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[n].data.fd,&ev);        curfds--;      }    }  }  close(listenfd);  return 0;}int handle(int connfd) {  int nread;  char buf[MAXLINE];  nread = read(connfd, buf, MAXLINE);//讀取客戶端socket流  if (nread == 0) {    printf("client close the connection/n");    close(connfd);    return -1;  }   if (nread < 0) {    perror("read error");    close(connfd);    return -1;  }    write(connfd, buf, nread);//響應客戶端   return 0;}

編譯

編譯和啟動服務端

gcc epollserver.c -o epollserver./epollserver

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到服務器教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 欧美激情性色生活片在线观看 | 毛片118极品美女写真 | 亚洲欧美天堂 | 亚洲一区二区三区精品在线观看 | 欧美精品v国产精品v日韩精品 | 亚洲国产精久久久久久久 | 校花被肉干高h潮不断 | 毛片在线视频在线播放 | 妇子乱av一区二区三区 | 久久成人动漫 | 极品美女一级毛片 | 欧美精品v国产精品v日韩精品 | 欧美日韩国产综合网 | 欧美黑大粗硬毛片视频 | 免费国产视频大全入口 | 久久久久久久免费看 | 一级做a爰性色毛片免费 | 亚洲视频在线免费看 | 2018亚洲男人天堂 | bt 自拍 另类 综合 欧美 | 午夜视频在线观看91 | 万圣街在线观看免费完整版 | 国产亚洲精品成人a | 视频一区国产 | 91精品国| 国产乱子视频 | 色综合激情 | 久久久久久久久久久久99 | 男女无遮挡羞羞视频 | 色综合网在线观看 | 黄色大片高清 | 国产精品区一区二区三区 | 成人三级视频在线观看 | a一级黄 | 欧美交在线 | 久久人人av| 一级毛片播放 | 狠狠干五月| 中文字幕在线免费看 | 美国黄色毛片女人性生活片 | 一区二区三区视频在线观看 |