伺服器端編程執行個體(二 單進程並發_IO多工)

來源:互聯網
上載者:User
 

2.1)select函數文法:       /* According to POSIX 1003.1-2001 */       #include <sys/select.h>        /* According to earlier standards */       #include <sys/time.h>       #include <sys/types.h>       #include <unistd.h>        int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);       int pselect(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t       *sigmask);        FD_CLR(int fd, fd_set *set);       FD_ISSET(int fd, fd_set *set);       FD_SET(int fd, fd_set *set);       FD_ZERO(fd_set *set); DESCRIPTION       The functions select and pselect wait for a number of file descriptors to change status. RETURN VALUE       On success, select and pselect return the number of descriptors contained in the descriptor sets, which may be zero if the timeout  expires before anything interesting happens. On error, -1 is returned, and errno is set appropriately; the sets and timeout become undefined, so do not rely on their contents after an error. 樣本:#include <stdio.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>int main (void){       fd_set rfds;       struct timeval tv;       int retval;        /* Watch stdin (fd 0) to see when it has input. */        FD_ZERO (&rfds);       FD_SET (0, &rfds);        FD_SET (1, &rfds);       FD_SET (2, &rfds);       FD_SET (4, &rfds);     /* Wait up to five seconds. */        tv.tv_sec = 5;       tv.tv_usec = 0;        retval = select (2, &rfds, NULL, NULL, &tv);    if (retval == -1)              perror ("select()");        else if (retval)    {              printf ("Data is available now./n");              printf( "retval=%d/n",retval);    }    /* FD_ISSET(0, &rfds) will be true. */     else              printf ("No data within five seconds./n");       return 0;}2.2)epollSYNOPSIS#include <sys/epoll.h> int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)int epoll_create(int size)int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout) 樣本:#include <iostream>#include <sys/socket.h>#include <sys/epoll.h>#include <netinet/in.h>#include <arpa/inet.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>#include <errno.h> #define MAXLINE 10#define OPEN_MAX 100#define LISTENQ 20#define SERV_PORT 5555#define INFTIM 1000 void setnonblocking(int sock){    int opts;    opts = fcntl(sock, F_GETFL);    if (opts < 0)    {        perror("fcntl(sock, GETFL)");        exit(1);    }    opts = opts|O_NONBLOCK;    if (fcntl(sock, F_SETFL, opts) < 0)    {        perror("fcntl(sock, SETFL, opts)");        exit(1);    }} int main(){    int i, maxi, listenfd, connfd, sockfd, epfd, nfds;    ssize_t n = 0;    char line[MAXLINE];    int l_sinSize = 0;    l_sinSize = sizeof(struct sockaddr);    //聲明epoll_event結構體的變數,ev用於註冊事件,數組用於回傳要處理的事件    struct epoll_event ev, events[20];//--------------------    //產生用於處理accept的epoll專用的檔案描述符    epfd = epoll_create(256);//-----------------------------    struct sockaddr_in clientaddr;    struct sockaddr_in serveraddr;    listenfd = socket(AF_INET, SOCK_STREAM, 0);    //把socket設定為非阻塞方式    setnonblocking(listenfd);//-----------------------------    //設定與要處理的事件相關的檔案描述符    ev.data.fd = listenfd;//--------------------------------    //設定要處理的事件類型    ev.events = EPOLLIN|EPOLLET;//--------------------------    //註冊epoll事件    epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev);//---------------------    bzero(&serveraddr, sizeof(struct sockaddr_in));    serveraddr.sin_family = AF_INET;    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);    serveraddr.sin_port = htons(SERV_PORT);    bind(listenfd, (struct sockaddr *)(&serveraddr), sizeof(struct sockaddr));    listen(listenfd, LISTENQ);    maxi = 0;    for ( ; ; ) {        //等待epoll事件的發生        nfds=epoll_wait(epfd,events,20,500);//---------------------------        //處理所發生的所有事件        for (i = 0; i < nfds; ++i)        {            if (events[i].data.fd == listenfd)            {                connfd = accept(listenfd, (struct sockaddr *)(&clientaddr), (socklen_t *)&l_sinSize);//------------                if (connfd < 0)                {                    perror("connfd < 0");                    exit(1);                }                setnonblocking(connfd);                char* str = inet_ntoa(clientaddr.sin_addr);                std::cout<<"connect from "<<str<<std::endl;                //設定用於讀操作的檔案描述符                ev.data.fd = connfd;                //設定用於注測的讀操作事件                ev.events = EPOLLIN|EPOLLET;                //註冊ev                epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);            }            else if (events[i].events&EPOLLIN)            {                if ((sockfd = events[i].data.fd) < 0)                {                    continue;                }                if ((n = read(sockfd, line, MAXLINE)) < 0)                {                    if (errno == ECONNRESET)                    {                        close(sockfd);                        events[i].data.fd = -1;                    }                    else                    {                        std::cout<<"readline error"<<std::endl;                    }                }                else if (n == 0)                {                    close(sockfd);                    events[i].data.fd = -1;                }                //設定用於寫操作的檔案描述符                ev.data.fd = sockfd;                //設定用於注測的寫操作事件                ev.events = EPOLLOUT|EPOLLET;                //修改sockfd上要處理的事件為EPOLLOUT                epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);            }            else if(events[i].events&EPOLLOUT)            {                sockfd = events[i].data.fd;                ssize_t l_writeSize = write(sockfd, line, n);                std::cout<<"write "<<l_writeSize<<std::endl;                //設定用於讀操作的檔案描述符                ev.data.fd = sockfd;                //設定用於注測的讀操作事件                ev.events = EPOLLIN|EPOLLET;                //修改sockfd上要處理的事件為EPOLIN                epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);            }        }    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.