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

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
<2025年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

常用鏈接

留言簿(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>
            国产精品一区免费视频| 免费在线观看精品| 欧美成人精品h版在线观看| 国产一区二区精品久久99| 亚洲欧美综合网| 亚洲欧美高清| 国产一区二区三区四区hd| 久久免费精品视频| 免费视频久久| 亚洲视频网站在线观看| 亚洲欧美国产77777| 国语自产精品视频在线看| 免费观看成人www动漫视频| 农夫在线精品视频免费观看| 亚洲美女毛片| 亚洲一区二区三区免费观看 | 日韩一级成人av| 国产精品日韩欧美一区二区| 久久一区二区三区四区| 亚洲国产高清在线| 夜夜嗨网站十八久久| 国产专区欧美专区| 亚洲国内自拍| 国产农村妇女毛片精品久久莱园子| 亚洲破处大片| 午夜亚洲性色福利视频| 亚洲一区二区免费| 欧美 日韩 国产精品免费观看| 国产精品呻吟| 亚洲精品日韩在线| 亚洲在线网站| 国产精品乱码妇女bbbb| 亚洲视频在线看| 欧美一区国产一区| 国产亚洲欧美激情| 久久久久久久久岛国免费| 老鸭窝毛片一区二区三区| 亚洲第一在线视频| 欧美xxx在线观看| 亚洲人永久免费| 一本色道**综合亚洲精品蜜桃冫| 欧美日韩三级电影在线| 亚洲午夜影视影院在线观看| 久久精品久久99精品久久| 狠狠色香婷婷久久亚洲精品| 久久综合成人精品亚洲另类欧美| 老司机亚洲精品| 99成人精品| 国产伦精品一区二区三区| 久久黄色影院| 最新国产成人在线观看| 午夜国产精品视频| 在线观看91久久久久久| 欧美三区视频| 久久久久.com| 99这里只有久久精品视频| 欧美一区亚洲二区| 91久久久国产精品| 国产精品综合不卡av | 日韩午夜一区| 久久久99国产精品免费| 91久久精品网| 国产女优一区| 欧美母乳在线| 久久精品夜色噜噜亚洲aⅴ| 最近中文字幕mv在线一区二区三区四区| 亚洲欧美国产一区二区三区| 亚洲二区在线视频| 国产精品网站在线观看| 欧美成人乱码一区二区三区| 午夜精品一区二区三区电影天堂| 欧美激情片在线观看| 久久精品女人| 亚洲一区二区三区色| 亚洲国产欧美不卡在线观看| 国产精品亚洲综合色区韩国| 欧美精品1区2区3区| 久久精品国产久精国产一老狼| 99国产精品久久久久久久久久 | 国产欧美日韩在线| 欧美精品亚洲| 久久人人爽人人爽| 性欧美1819性猛交| 日韩视频免费大全中文字幕| 美女啪啪无遮挡免费久久网站| 亚洲欧美日韩中文播放| 亚洲精选视频在线| 亚洲电影视频在线| 狠狠色狠狠色综合| 国产视频精品网| 国产精品视频xxxx| 欧美性猛交视频| 欧美另类人妖| 欧美黄色影院| 奶水喷射视频一区| 老鸭窝91久久精品色噜噜导演| 欧美伊人久久久久久久久影院| 中文av字幕一区| 在线午夜精品自拍| 一本久道久久综合婷婷鲸鱼| 亚洲欧洲在线一区| 亚洲精品123区| 亚洲国产清纯| 亚洲人屁股眼子交8| 亚洲三级影院| 亚洲乱码国产乱码精品精天堂| 亚洲经典视频在线观看| 91久久精品一区二区三区| 亚洲国产99| 亚洲精品美女久久7777777| 亚洲成人自拍视频| 亚洲精品欧美在线| 一区二区三区精品久久久| 亚洲最新视频在线| 亚洲一区亚洲二区| 欧美资源在线观看| 老司机免费视频一区二区| 欧美~级网站不卡| 欧美激情一级片一区二区| 欧美老女人xx| 国产精品欧美一区喷水| 国产亚洲精久久久久久| 伊人成综合网伊人222| 亚洲欧洲日产国产网站| 中文av一区二区| 欧美与欧洲交xxxx免费观看 | 99这里只有精品| 亚洲欧美日本精品| 久久久久免费观看| 欧美激情麻豆| 国产精品一二三四区| 影音先锋国产精品| 99视频在线精品国自产拍免费观看 | 亚洲欧美视频在线| 午夜精品久久| 另类天堂av| 麻豆久久久9性大片| 欧美日本一区| 国产女同一区二区| 亚洲激情在线观看| 亚洲欧美日韩国产中文在线| 久久久久久综合| 91久久精品国产91性色tv| 宅男精品视频| 久久久久久日产精品| 欧美视频在线观看视频极品| 韩国欧美一区| 亚洲婷婷在线| 欧美91大片| 亚洲自拍偷拍视频| 欧美电影在线免费观看网站| 国产精品尤物| 一本色道久久综合狠狠躁篇怎么玩| 亚洲摸下面视频| 亚洲高清自拍| 久久国产精品久久w女人spa| 欧美日韩国产色综合一二三四| 极品少妇一区二区三区精品视频| 一区二区三区高清在线观看| 乱人伦精品视频在线观看| 中文在线一区| 欧美久久久久免费| 亚洲高清在线观看| 久久久91精品国产一区二区三区| 亚洲三级电影全部在线观看高清| 久久精品视频免费| 国产精品一二| 亚洲午夜激情| 亚洲日本黄色| 欧美 日韩 国产在线 | 黄色在线成人| 亚洲欧美中文在线视频| 亚洲乱码国产乱码精品精天堂| 欧美在线视频免费| 国产欧美高清| 亚洲欧美视频一区二区三区| 亚洲日本中文| 欧美激情精品久久久久久| 亚洲成人原创| 久久久久久久999精品视频| 亚洲一本大道在线| 欧美性猛交xxxx乱大交蜜桃 | 亚洲人成欧美中文字幕| 久久久天天操| 欧美一区二区免费| 国产精品制服诱惑| 欧美在线视频全部完| 亚洲一区尤物| 国产精品视频999| 欧美在线在线| 欧美一级午夜免费电影| 国产一区二区激情| 久久亚洲影院| 久久亚洲精品中文字幕冲田杏梨 | 亚洲第一区在线观看| 男同欧美伦乱| 免费观看久久久4p| 日韩视频免费| 一区二区三区蜜桃网| 国产精品视频yy9299一区|