UNIX TCP回射伺服器/用戶端(4):使用epoll模型的伺服器

來源:互聯網
上載者:User

    《Unix網路編程》這本書附帶了許多短小精美的小程式,我在閱讀此書的時候,將書上的代碼按照自己的理解重寫了一遍(大部分是抄書上的),加深一下自己的理解(純看書太困了,呵呵)。此例子在Ubuntu10.04上測試通過。

    PS:程式裡使用了包裹函數(首字母是大寫的函數)和常量(所有字母都是大寫的常量)的聲明在my_unp.h檔案中,定義在unp_base.c和unp_thread.c中,地址:http://blog.csdn.net/aaa20090987/article/details/8096701

    程式簡介:這是一個運用epoll系列函數進行IO複用的伺服器模型。它是目前UNIX與LINUX平台上效率最高,最受歡迎的IO複用傳輸模型。

上代碼:

#include "my_unp.h"    int main(void)    {        int listenfd, connfd, sockfd, epfd;      int i, maxi, nfds;      ssize_t n;        char buf[MAXLINE];        socklen_t clilen;        struct sockaddr_in cliaddr;        struct sockaddr_in servaddr;         //聲明epoll_event結構體的變數,ev用於註冊事件,數組用於回傳要處理的事件        struct epoll_event ev, events[256];          //建立一個epoll的控制代碼,size用來告訴核心這個監聽的數目一共有多大        epfd = Epoll_create(256);         //建立用於TCP協議的通訊端          listenfd = Socket(AF_INET, SOCK_STREAM, 0);        memset(&servaddr, 0, sizeof(servaddr));        servaddr.sin_family = AF_INET;        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);        servaddr.sin_port = htons(SERV_PORT);          //把socket和socket地址結構聯絡起來         Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));       //開始監聽LISTENQ連接埠         Listen(listenfd, LISTENQ);        //設定與要處理的事件相關的檔案描述符和事件      ev.data.fd = listenfd;        ev.events = EPOLLIN|EPOLLET;          //註冊epoll事件        Epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd,&ev);        maxi = 0;        while(1)      {            //等待epoll事件的發生            //返回需要處理的事件數目nfds,如返回0表示已逾時。            nfds = Epoll_wait(epfd, events, 20, 500);              //處理所發生的所有事件            for(i=0; i < nfds; ++i)            {                //如果新監測到一個SOCKET使用者串連到了綁定的SOCKET連接埠,建立新的串連。                if(events[i].data.fd == listenfd)                {                    connfd = Accept(listenfd,(SA*)&cliaddr, &clilen);                     printf("connection from %s, port %d.\n",                            Inet_ntop(AF_INET, (void*)&cliaddr.sin_addr, buf, sizeof(buf)),                            ntohs(cliaddr.sin_port));                       //設定用於讀操作的檔案描述符和事件                  ev.data.fd = connfd;                    ev.events = EPOLLIN|EPOLLET;                      //註冊事件                  Epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);               }                  //如果是已經串連的使用者,並且收到資料,那麼進行讀入。                else if(events[i].events & EPOLLIN)                {                    sockfd = events[i].data.fd;                  if ( sockfd < 0 )                        continue;                    n = read(sockfd, buf, MAXLINE);                  if ( n < 0)                     {                          // Connection Reset:你串連的那一端已經斷開了,                      //而你卻還試著在對方已斷開的socketfd上讀寫資料!                        if (errno == ECONNRESET)                        {                            Close(sockfd);                            events[i].data.fd = -1;                        }                         else                            error_quit("read error");                  }                     //如果讀入的資料為空白                    else if ( n == 0 )                   {                        Close(sockfd);                        events[i].data.fd = -1;                    }                    else                  {                      //設定用於寫操作的檔案描述符和事件                      ev.data.fd = sockfd;                      ev.events = EPOLLOUT|EPOLLET;                      //註冊事件                      Epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);                  }              }                //如果有資料發送              else if(events[i].events & EPOLLOUT)               {                  sockfd = events[i].data.fd;                  Writen(sockfd, buf, n);                      //設定用於讀操作的檔案描述符和事件                  ev.data.fd = sockfd;                  ev.events = EPOLLIN|EPOLLET;                    //註冊事件                  Epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);              }          }      }      return 0;    }   

與其配套的用戶端在這裡:http://blog.csdn.net/aaa20090987/article/details/8462262

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.