青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 297,  comments - 15,  trackbacks - 0
[轉]epoll用法說明(源代碼)


epoll用到的所有函數都是在 頭文件sys/epoll.h中聲明的,下面簡要說明所用到的數據結構和函數:
所用到的數據結構
typedef union epoll_data {
                void *ptr;
                int fd;
                __uint32_t u32;
                __uint64_t u64;
        } epoll_data_t;

        struct epoll_event {
                __uint32_t events;      /* Epoll events */
                epoll_data_t data;      /* User data variable */
        };
結構體 epoll_event 被用于注冊所感興趣的事件和回傳所發生待處理的事件,其中epoll_data 聯合體用來保存觸發事件的某個文件描述符相關的數據,例如一個client連接到服務器,服務器通過調用accept函數可以得到于這個client對應 的socket文件描述符,可以把這文件描述符賦給epoll_data的fd字段以便后面的讀寫操作在這個文件描述符上進行。epoll_event 結構體的events字段是表示感興趣的事件和被觸發的事件可能的取值為:EPOLLIN :表示對應的文件描述符可以讀;
EPOLLOUT:表示對應的文件描述符可以寫;
EPOLLPRI:表 示對應的文件描述符有緊急的數據可讀(我不太明白是什么意思,可能是類似client關閉  socket連接這樣的事件);
EPOLLERR:表 示對應的文件描述符發生錯誤;
EPOLLHUP:表示對應的文件描述符被掛斷;
EPOLLET:表 示對應的文件描述符有事件發生;
所用到的函數:
1、epoll_create函數
     函數聲明:int epoll_create(int size)
    該函數生成一個epoll專用的文件描述符,其中的參數是指定生成描述符的最大范圍(我覺得這個參數和select函數的第一個參數應該是類似的但是該怎 么設置才好,我也不太清楚)。
2、epoll_ctl函數
     函數聲明:int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
    
該函數用于控制某個文件描述符上的事 件,可以注冊事件,修改事件,刪除事件。
    參數:epfd:由 epoll_create 生成的epoll專用的文件描述符;
                op:要進行的操作例如注冊事件,可能的取值EPOLL_CTL_ADD 注冊、EPOLL_CTL_MOD
                        改、EPOLL_CTL_DEL 刪除
                fd:關聯的文件描述符;
                event:指向epoll_event的指針;
    如果調用成功返回0,不成功返回-1
3、epoll_wait函數
函數聲明:int epoll_wait(int epfd,struct epoll_event * events,int maxevents,int timeout)

該函數用于輪詢I/O事件的發生;
參數:
epfd:由epoll_create 生成的epoll專用的文件描述符;
epoll_event:用于回傳代處理事件的數組;
maxevents:每次能處理的事件數;
timeout: 等待I/O事件發生的超時值;
返回發生事件數。
例子:


 #include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <sys/time.h>
#include <sys/resource.h>


#define MAXBUF 1024
#define MAXEPOLLSIZE 10000

/*
setnonblocking - 設置句柄為非阻塞方式
*/
int setnonblocking(int sockfd)
{
    if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1) {
        return -1;
    }
    return 0;
}

/*
handle_message - 處理每個 socket 上的消息收發
*/
int handle_message(int new_fd)
{
    char buf[MAXBUF + 1];
    int len;
    /* 開始處理每個新連接上的數據收發 */
    bzero(buf, MAXBUF + 1);
    /* 接收客戶端的消息 */
    len = recv(new_fd, buf, MAXBUF, 0);
    if (len > 0)
        printf
            ("%d接收消息成功:'%s',共%d個字節的數據\n",
             new_fd, buf, len);
    else {
        if (len < 0)
            printf
                ("消息接收失敗!錯誤代碼是%d,錯誤信息是'%s'\n",
                 errno, strerror(errno));
        close(new_fd);
        return -1;
    }
    /* 處理每個新連接上的數據收發結束 */
    return len;
}
/************ 關于本文檔********************************************
*filename: epoll-server.c
*purpose: 演示epoll處理海量socket連接的方法
*wrote by: zhoulifa(zhoulifa@163.com) 周立發(http://zhoulifa.bokee.com)
Linux愛好者 Linux知識傳播者 SOHO族 開發者 最擅長C語言
*date time:2007-01-31 21:00
*Note: 任何人可以任意復制代碼并運用這些文檔,當然包括你的商業用途
* 但請遵循GPL
*Thanks to:Google
*Hope: 希望越來越多的人貢獻自己的力量,為科學技術發展出力
* 科技站在巨人的肩膀上進步更快!感謝有開源前輩的貢獻!
*********************************************************************/
int main(int argc, char **argv)
{
    int listener, new_fd, kdpfd, nfds, n, ret, curfds;
    socklen_t len;
    struct sockaddr_in my_addr, their_addr;
    unsigned int myport, lisnum;
    struct epoll_event ev;
    struct epoll_event events[MAXEPOLLSIZE];
    struct rlimit rt;

    if (argv[1])
        myport = atoi(argv[1]);
    else
        myport = 7838;

    if (argv[2])
        lisnum = atoi(argv[2]);
    else
        lisnum = 2;

    /* 設置每個進程允許打開的最大文件數 */
    rt.rlim_max = rt.rlim_cur = MAXEPOLLSIZE;
    if (setrlimit(RLIMIT_NOFILE, &rt) == -1) {
        perror("setrlimit");
        exit(1);
    }
    else printf("設置系統資源參數成功!\n");

    /* 開啟 socket 監聽 */
    if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    } else
        printf("socket 創建成功!\n");

    setnonblocking(listener);

    bzero(&my_addr, sizeof(my_addr));
    my_addr.sin_family = PF_INET;
    my_addr.sin_port = htons(myport);
    if (argv[3])
        my_addr.sin_addr.s_addr = inet_addr(argv[3]);
    else
        my_addr.sin_addr.s_addr = INADDR_ANY;

    if (bind
        (listener, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))
        == -1) {
        perror("bind");
        exit(1);
    } else
        printf("IP 地址和端口綁定成功\n");

    if (listen(listener, lisnum) == -1) {
        perror("listen");
        exit(1);
    } else
        printf("開啟服務成功!\n");

    /* 創建 epoll 句柄,把監聽 socket 加入到 epoll 集合里 */
    kdpfd = epoll_create(MAXEPOLLSIZE);
    len = sizeof(struct sockaddr_in);
    ev.events = EPOLLIN | EPOLLET;
    ev.data.fd = listener;
    if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, listener, &ev) < 0) {
        fprintf(stderr, "epoll set insertion error: fd=%d\n", listener);
        return -1;
    } else
        printf("監聽 socket 加入 epoll 成功!\n");
    curfds = 1;
    while (1) {
        /* 等待有事件發生 */
        nfds = epoll_wait(kdpfd, events, curfds, -1);
        if (nfds == -1) {
            perror("epoll_wait");
            break;
        }
        /* 處理所有事件 */
        for (n = 0; n < nfds; ++n) {
            if (events[n].data.fd == listener) {
                new_fd = accept(listener, (struct sockaddr *) &their_addr,
                                &len);
                if (new_fd < 0) {
                    perror("accept");
                    continue;
                } else
                    printf("有連接來自于: %d:%d, 分配的 socket 為:%d\n", inet_ntoa(their_addr.sin_addr), ntohs(their_addr.sin_port), new_fd);

                setnonblocking(new_fd);
                ev.events = EPOLLIN | EPOLLET;
                ev.data.fd = new_fd;
                if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, new_fd, &ev) < 0) {
                    fprintf(stderr, "把 socket '%d' 加入 epoll 失敗!%s\n",
                            new_fd, strerror(errno));
                    return -1;
                }
                curfds++;
            } else {
                ret = handle_message(events[n].data.fd);
                if (ret < 1 && errno != 11) {
                    epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[n].data.fd,
                              &ev);
                    curfds--;
                }
            }
        }
    }
    close(listener);
    return 0;
}

編 譯此程序用命令:
gcc -Wall epoll-server.c -o server

運行此程序需要具有管理員權限!

sudo ./server 7838 1

通過測試這一個服務器可能同時處理10000 -3 = 9997 個連接!

如果這是 一個在線服務系統,那么它可以支持9997人同時在線,比如游戲、聊天等。
 原文地址 http://blog.chinaunix.net/u/8818/showart_440623.html
posted on 2010-05-06 12:03 chatler 閱讀(675) 評論(0)  編輯 收藏 引用 所屬分類: Socket
<2010年5月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

常用鏈接

留言簿(10)

隨筆分類(307)

隨筆檔案(297)

algorithm

Books_Free_Online

C++

database

Linux

Linux shell

linux socket

misce

  • cloudward
  • 感覺這個博客還是不錯,雖然做的東西和我不大相關,覺得看看還是有好處的

network

OSS

  • Google Android
  • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
  • os161 file list

overall

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲天堂av综合网| 国产乱人伦精品一区二区| 免费一级欧美片在线观看| 欧美激情一二三区| 国产日韩欧美制服另类| 亚洲大胆在线| 午夜视频在线观看一区二区| 欧美成人高清视频| 亚洲欧美国产毛片在线| 欧美日本韩国| 亚洲乱码视频| 欧美成黄导航| 欧美日本久久| 久久不射中文字幕| 亚洲午夜视频在线| 国产色综合网| 亚洲国产精品激情在线观看| 欧美在线视频一区二区三区| 欧美一区高清| 国产亚洲在线| 久久精品视频网| 亚洲欧美综合精品久久成人| 欧美视频不卡中文| 一区二区日韩| 亚洲六月丁香色婷婷综合久久| 久久久久久有精品国产| 国产一区二区三区不卡在线观看| 欧美国产日韩一区| 久久欧美肥婆一二区| 国内精品久久久久久久影视蜜臀 | 国产精品青草久久| 亚洲综合色自拍一区| 亚洲乱码国产乱码精品精天堂| 国产欧美日韩三区| 久久婷婷丁香| 蜜桃av一区二区三区| 在线观看一区欧美| 亚洲天堂成人在线视频| 亚洲国产一区二区三区a毛片| 老**午夜毛片一区二区三区| 午夜精品www| 一卡二卡3卡四卡高清精品视频| 亚洲精品综合在线| 1024精品一区二区三区| 午夜免费电影一区在线观看| 在线成人av网站| 亚洲欧洲日本在线| 国产精品videossex久久发布| 日韩一区二区精品| 日韩亚洲欧美成人一区| 国产精品成人观看视频国产奇米| 欧美亚洲免费电影| 久久久97精品| 一道本一区二区| 欧美国产另类| 亚洲免费中文| 久久久国产视频91| 久久精品主播| 欧美日本中文字幕| 久久国产精品高清| 国产精品一区二区久久国产| 一区二区三区国产在线| 精品va天堂亚洲国产| 亚洲精品久久久久久一区二区| 国产精品视频久久久| 一区二区国产精品| 亚洲一区二区三区四区五区黄| 午夜在线精品| 久久国产精品久久w女人spa| 国产亚洲精品激情久久| 欧美一站二站| 亚洲天堂av电影| 久久夜色精品国产噜噜av| 久久综合久久综合久久| 一区二区三区在线视频播放| 久久在线免费观看| 久久精品视频免费观看| 狠狠色狠狠色综合日日小说| 一区二区三区日韩欧美| 性色av一区二区三区| 国产亚洲一区在线播放| 久久久久网址| 亚洲精品视频在线观看免费| 亚洲制服丝袜在线| 国模大胆一区二区三区| 猫咪成人在线观看| 亚洲精品影院| 久久久www成人免费无遮挡大片 | 欧美日韩精品欧美日韩精品| 一区二区三区久久精品| 久久久999成人| 亚洲国产精品成人综合色在线婷婷 | 国产精品拍天天在线| 久久久精品免费视频| 亚洲人成网站777色婷婷| 亚洲综合国产| 亚洲国产精品福利| 国产精品草莓在线免费观看| 久久久久.com| 中国成人亚色综合网站| 在线综合亚洲欧美在线视频| 国产精品午夜电影| 美女精品在线| 午夜一级久久| 日韩视频免费大全中文字幕| 久久精品日韩一区二区三区| 亚洲三级视频| 欧美日韩三级电影在线| 99re国产精品| 免费影视亚洲| 亚洲精品一区二区在线| 国产精品色在线| 欧美激情一区二区三区四区| 性亚洲最疯狂xxxx高清| 久久爱www.| 玖玖视频精品| 羞羞视频在线观看欧美| 一本色道久久综合| 亚洲激情欧美激情| 国产一区二区三区久久悠悠色av| 欧美日韩亚洲精品内裤| 美女尤物久久精品| 久久精品国内一区二区三区| 一本色道久久综合亚洲精品不卡 | 亚洲一级网站| 亚洲免费激情| 最新亚洲激情| 国产精品久久久久久五月尺| 欧美一区二区三区在线视频 | 亚洲视频福利| 亚洲免费电影在线观看| 亚洲国产老妈| 久久免费视频这里只有精品| 亚洲国产三级网| 黄色精品一区二区| 国产日韩欧美一区二区三区四区| 国产精品xxxxx| 欧美午夜一区| 国产精品久久夜| 国产精品麻豆成人av电影艾秋| 欧美日韩在线三级| 欧美午夜在线视频| 国产精品久久福利| 国产精品久久久一本精品| 国产精品久久二区| 国产九九视频一区二区三区| 国产日韩欧美视频| 国产一区二区观看| 韩日欧美一区二区三区| 精品91在线| 亚洲国产91| 一区二区免费在线观看| 亚洲香蕉成视频在线观看| 午夜精品福利在线观看| 销魂美女一区二区三区视频在线| 欧美在线在线| 欧美**人妖| 亚洲乱码国产乱码精品精98午夜| 一区二区欧美日韩视频| 亚洲欧美国产一区二区三区| 午夜天堂精品久久久久| 久久精品国产精品亚洲综合| 久久久噜噜噜久久人人看| 蜜臀av国产精品久久久久| 欧美激情精品久久久久久变态| 欧美日韩国产成人精品| 国产精品毛片a∨一区二区三区|国| 国产精品综合av一区二区国产馆| 国内精品久久久久伊人av| 亚洲欧洲一二三| 亚洲欧美在线高清| 男女激情视频一区| 日韩视频在线观看国产| 欧美一区二区性| 欧美激情乱人伦| 国产欧美日韩视频一区二区| 亚洲破处大片| 午夜免费电影一区在线观看| 蜜臀久久99精品久久久久久9| 亚洲精品一区二区三区四区高清| 亚洲一区久久久| 亚洲午夜激情| 美女任你摸久久| 国产日本欧美一区二区三区| 亚洲精品小视频| 欧美在线一区二区| 亚洲免费播放| 美日韩精品视频| 国产日韩欧美另类| 一区二区三区国产盗摄| 久久亚洲国产精品一区二区| 99精品国产在热久久| 欧美日韩国产999| 国产精品麻豆成人av电影艾秋 | 欧美日韩国产综合久久| 国内精品福利| 亚洲永久精品大片| 91久久综合| 美女国产一区| 在线观看亚洲精品|