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

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 閱讀(678) 評論(0)  編輯 收藏 引用 所屬分類: Socket
<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用鏈接

留言簿(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>
            亚洲精品在线观看视频| 136国产福利精品导航网址| 亚洲美女在线观看| 日韩视频不卡| 国产精品伦一区| 久久精品99久久香蕉国产色戒| 亚洲午夜激情| 好看不卡的中文字幕| 欧美成人综合| 欧美日韩国产一区二区三区| 亚洲永久免费| 欧美在线视频观看免费网站| 亚洲电影免费在线观看| 亚洲电影免费观看高清完整版在线 | 在线欧美日韩精品| 亚洲国产精品一区二区久| 欧美视频一区二区三区| 欧美在线日韩| 欧美国产视频日韩| 亚洲男人影院| 久久免费的精品国产v∧| 一区二区三区高清视频在线观看| 亚洲午夜高清视频| 亚洲人在线视频| 亚洲欧美国产三级| 亚洲精品日本| 欧美在线免费观看| 一本综合精品| 久久精品一区四区| 亚洲男同1069视频| 毛片基地黄久久久久久天堂| 亚洲永久免费av| 欧美不卡视频一区| 久久精品国产免费| 欧美日韩亚洲国产精品| 蜜月aⅴ免费一区二区三区| 欧美午夜精品久久久久久浪潮| 久久在线视频在线| 国产精品视频一| 亚洲欧洲三级电影| 亚洲国产精品va在线看黑人动漫| 亚洲网站在线| 日韩午夜电影在线观看| 久久久久国产精品www | 国产一区二区精品久久99| 亚洲人成在线影院| 亚洲电影在线| 久久电影一区| 久久精品麻豆| 国产精品区一区二区三区| 亚洲精品系列| 日韩午夜电影在线观看| 久久综合中文色婷婷| 麻豆成人小视频| 国产亚洲成精品久久| 亚洲图片欧洲图片日韩av| 宅男在线国产精品| 欧美日韩成人一区| 最新国产拍偷乱拍精品| 亚洲精品国产品国语在线app| 久久久久久九九九九| 久久久噜噜噜久久人人看| 国产真实乱偷精品视频免| 性久久久久久久久| 久久精品盗摄| 国产又爽又黄的激情精品视频| 亚洲免费在线看| 欧美亚洲尤物久久| 国产一区二区久久| 久久久夜色精品亚洲| 久久免费视频在线观看| 黄色免费成人| 女女同性女同一区二区三区91| 欧美成在线观看| 亚洲日本无吗高清不卡| 欧美另类在线观看| 亚洲美女性视频| 亚洲免费在线播放| 国产亚洲一区二区三区在线观看| 欧美亚洲色图校园春色| 久久青青草原一区二区| 亚洲黄网站黄| 欧美日韩美女在线观看| 亚洲一区二区在线观看视频| 久久久久国产精品一区三寸| 亚洲承认在线| 欧美色区777第一页| 性欧美大战久久久久久久久| 免费亚洲电影| 亚洲一二三区在线| 国产一区在线看| 欧美精品高清视频| 亚洲欧美综合v| 亚洲成人自拍视频| 亚洲免费视频网站| 在线免费观看日本一区| 欧美日韩亚洲成人| 久久高清一区| 亚洲最快最全在线视频| 久久久久久久久久久久久9999| 亚洲小视频在线| 午夜影院日韩| 经典三级久久| 欧美亚洲不卡| 老司机凹凸av亚洲导航| 一本色道久久精品| 麻豆9191精品国产| 亚洲一区二区免费看| 黄色精品一区| 欧美视频一区二区在线观看| 久久精品国产一区二区三| 亚洲欧洲在线看| 欧美中文字幕第一页| 亚洲精品综合| 精品电影一区| 国产精品区免费视频| 欧美激情国产高清| 久久久久久电影| 午夜免费日韩视频| 这里只有视频精品| 亚洲精品无人区| 午夜天堂精品久久久久| 黑人操亚洲美女惩罚| 欧美视频四区| 欧美激情综合在线| 久久漫画官网| 欧美一区二区三区另类| 亚洲视频一二三| 日韩视频一区| 亚洲人www| 亚洲黄色一区| 亚洲国产婷婷综合在线精品 | 91久久精品国产91性色| 国产亚洲精品成人av久久ww| 欧美日韩一区二区精品| 欧美伦理影院| 欧美精品在线观看| 欧美国产精品久久| 欧美国产日韩一区| 欧美成人免费小视频| 另类激情亚洲| 久色成人在线| 欧美 日韩 国产一区二区在线视频| 亚洲一区二区三区在线播放| 久久综合一区| 久久精品国产亚洲a| 午夜老司机精品| 欧美一级精品大片| 欧美一区二区黄色| 久久国产精品久久w女人spa| 欧美一区二区三区四区高清| 午夜精品三级视频福利| 欧美一区二区三区免费视| 欧美一乱一性一交一视频| 久久aⅴ国产欧美74aaa| 久久综合九色综合久99| 免费一级欧美片在线观看| 亚洲风情亚aⅴ在线发布| 亚洲欧洲在线免费| 一本色道精品久久一区二区三区 | 午夜视频久久久久久| 香蕉久久国产| 久久久亚洲国产美女国产盗摄| 蜜臀a∨国产成人精品| 亚洲国产成人在线播放| 久久久99爱| 国产日韩欧美不卡在线| 国产精品视频999| 国产曰批免费观看久久久| 国产一区日韩欧美| 亚洲欧洲在线视频| 亚洲综合国产激情另类一区| 欧美亚洲网站| 欧美成人tv| 亚洲色图综合久久| 欧美一级理论性理论a| 久久久久久久久久久久久9999| 欧美高清视频免费观看| 国产精品永久免费视频| 18成人免费观看视频| 亚洲一区二区在线观看视频| 久久人人爽人人爽| 99国产精品久久久久老师| 亚洲女与黑人做爰| 欧美久久久久久久久久| 国产综合av| 亚洲自拍偷拍福利| 国产精品青草久久久久福利99| 国产精品白丝av嫩草影院| 好男人免费精品视频| 一本色道久久综合亚洲精品按摩 | 欧美电影免费观看网站| 日韩亚洲欧美一区| 快射av在线播放一区| 国产精品视频观看| 9i看片成人免费高清| 欧美91大片| 欧美一区不卡| 国产精品露脸自拍| 在线视频日本亚洲性|