好湿?好紧?好多水好爽自慰,久久久噜久噜久久综合,成人做爰A片免费看黄冈,机机对机机30分钟无遮挡

主頁 > 知識庫 > Linux IO多路復用之epoll網絡編程

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

熱門標簽:安陽ai電銷機器人軟件 外呼系統的經營范圍 申請400電話價格多少 云會外呼系統 智能電話機器人坐席 涪陵商都400電話開通辦理 廈門營銷外呼系統平臺 柳州市機器人外呼系統報價 外呼系統不彈窗

前言

本章節是用基本的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 10240
int 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

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。如果你想了解更多相關內容請查看下面相關鏈接

標簽:晉城 福州 綏化 撫順 巴中 孝感 蕪湖 南充

巨人網絡通訊聲明:本文標題《Linux IO多路復用之epoll網絡編程》,本文關鍵詞  Linux,多路,復,用之,epoll,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Linux IO多路復用之epoll網絡編程》相關的同類信息!
  • 本頁收集關于Linux IO多路復用之epoll網絡編程的相關信息資訊供網民參考!
  • 推薦文章
    主站蜘蛛池模板: 91麻豆天美传媒在线无码 | 少妇护士的婬乱和放荡| 青娱极品盛宴免费盛宴| 欧美成人hd| 人妻淑芬的沉沦1~46| 美女光屁股免费视频老师| 黄网站色| 曰漫无羞遮无删减动漫| 色婷婷一区二区三区四区成人网站| jizzjizz5hd日本护士| 中国人奶水xxxhd牛奶| 医生掀开奶罩边躁边狠狠躁视频| 欧美精品系列产品| 激情另类偷拍亚洲小说| 毛片免费全部播放观看中文 | 杨幂裸乳被爆?白浆的视频| 韩国一级片视频| 精产国品一二三产品天堂| 国产麻豆剧果冻传媒浮生影视高清| 国产精品秘?入口久久熟女| 波多野结衣免费视频| 成人H漫画精精一区二区器材| 翁熄性放纵第六篇| 日本残忍极度灌浣肠视频| barazzaHD4k欧美| 春欲深(np高h)完整版| 九九爱www高清免费人成| 精品精品国产高清a毛片 | freehd18xxxx中国| 国产精品福利视频一区二区| 抬高在体内横冲直撞| 久久国产福利| 我和岳m愉情XXXX国产| 欧美熟妇AV欧差AA片欧米茄| 老司机精品在线| 亚洲欧美日韩中文字幕| 八佰电影免费观看正版| 男揉女奶gif动态图| 国产精品一品二区三区的使用体验| a毛片基地免费全部香蕉| 别揉我胸啊嗯上课啊|