FrontPage|FindPage|TitleIndex|RecentChanges|RSS Epoll Echo
 

1 Listen() ÇÔ¼ö ±¸Çö
2 ?OnEvent() ¿Í ?OnError()ÀÇ ±¸Çö
3 main()ÀÇ ±¸Çö
4 ¼Ò½ºÆÄÀÏ
5 ÀÌÈÄ °³¼±


1 Listen() ÇÔ¼ö ±¸Çö #

¼­¹ö ±¸ÇöÀ» Çϱâ À§ÇØ ÇÊ¿¬ÀûÀ¸·Î listen ÄÝÀ» ÇؾßÇÏÁö¸¸, °ÅÀÇ ¸Å¹ø º¹»çÇؼ­ ³Ö´Ùº¸´Ï ±×°Íµµ ±ÍÂú¾Æ¼­ µû·Î ºÐ¸®¸¦ ÇØ º¸¾Ò´Ù. ±×³É Listen(Æ÷Æ®¹øÈ£) ÄÝ ÇØÁÖ¸é µÇ°í ¼º°ø½Ã¿¡´Â fd ³Ñ¹ö, ½ÇÆнÿ¡´Â À½¼ö°ªÀÇ ¿¡·¯Äڵ带 ¸®ÅÏÇϵµ·Ï ÀÛ¼º.
int Listen(const unsigned nport)
{
    struct sockaddr_in server_addr, client_addr;
    int one=1, addrlen = sizeof(struct sockaddr_in);
    int fd_listen;

    if ((fd_listen = socket(PF_INET, SOCK_STREAM, 0)) < 0) return -1;

    bzero((char *)&server_addr, sizeof(server_addr));
    server_addr.sin_family      = PF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port        = htons(nport);

    setsockopt(fd_listen, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));

    if((bind(fd_listen, (struct sockaddr *)&server_addr, sizeof(server_addr))) < 0 ){
        close(fd_listen);
        return -2;
    }

    if(listen(fd_listen, MAX_PENDING) < 0){
        close(fd_listen);
        return -3;
    }

    return fd_listen;
}

2 ?OnEvent() ¿Í ?OnError()ÀÇ ±¸Çö #

int OnError(const int fd, const int errcode)
{
    return errcode;
}

int OnEvent(TEpollEvent &event)
{
    int nread, nwrite;
    char buf[1024];

    if( event.events & EPOLLIN ){
        // ³ªÁß¿¡ OnRead(); ·Î ¹Ù²Ü°ÍÀÌ´Ù.
        nread = read(event.data.fd, buf, 1024);

        if( nread < 1) return OnError(event.data.fd, nread);
        else {
            nwrite = write(event.data.fd, buf, nread);
            buf[0] = 0;
        }
    }
    if( event.events & EPOLLOUT){
        // ³ªÁß¿¡ OnWrite(); ·Î ¹Ù²Ü°ÍÀÌ´Ù.
    }
    if( event.events & EPOLLERR) return OnError(event.data.fd, -1);

    return 1;
}

Read À̺¥Æ®, Áï EPOLLIN ÀÌ ¹ß»ýÇßÀ»¶§¿¡ µ¥ÀÌÅ͸¦ ÀÐ°í ¹Ù·Î ¶Ç send(write) Çϵµ·Ï ÀÛ¼ºÇß´Ù. nwrite°¡ nread ¿Í °°ÀÌ ¾ÊÀ» °æ¿ì¿¡ ´ëÇÑ Ã³¸® (Áï, Àü¼Û°úÁ¤¿¡¼­ÀÇ ¿¡·¯¹ß»ý)´Â ¿©±â¼­´Â Á¦¿ÜÇÏ°í °£·«ÇÏ°Ô ÀÛ¼ºÇÏ¿´´Ù. ¿ª½Ã ³ªÁß¿¡ ?SendBuffering ¹æ½ÄÀ¸·Î °íÃļ­, ?OnWrite ¿¡¼­ flush Çϵµ·Ï º¸¿ÏµÇ¾î¾ß WOULDBLOCK»óȲ¿¡ ´ëÇØ ´ëºñÇÒ ¼ö ÀÖ´Ù.


Read °úÁ¤¿¡¼­ ¿¡·¯°¡ ¹ß»ýÇßÀ» °æ¿ì´Â ´ëºÎºÐ ¿¬°áÀÌ ²÷¾îÁ®¼­ ¹ß»ýÇÑ´Ù. ÀÌ Äڵ忡¼­´Â ¹Ù·Î ?OnError 󸮸¦ Çϵµ·Ï Çߴµ¥, ¸ÞÀÎÇÔ¼ö¿¡¼­´Â ?OnEvent ¿¡¼­ 1º¸´Ù ÀÛÀº°ª ( result < 1) ÀÎ °æ¿ì¿¡ epoll °ü½Éfd¿¡¼­ »èÁ¦ÇÏ°í, ¿¬°áÀ» ´Ýµµ·Ï(close) ÀÛ¼ºÇÏ¿´´Ù.

3 main()ÀÇ ±¸Çö #

epoll °´Ã¼ ¼±¾ð
int main(void)
{
    ....
    TEpoll epoll(MAX_CLIENT);
    TEpollEvent events[MAX_EVENTS];

    .... 

    if(! epoll.is_epoll_init){
        perror("epoll init error\n");
        exit(-1);
    }
    ....


?TEpollÀÇ ÀνºÅϽº epoll À» »ý¼ºÇÏ¿´´Ù. MAX_CLIENT´Â c10k°¡ °¡´ÉÇÏ´Ù´Â °Í ¶§¹®¿¡ ÀϺη¯ 10,000 À¸·Î Á¤ÀÇÇÏ¿´´Ù ^^; ?TEpollEvent´Â ´Ü¼øÈ÷ epoll_eventÀÇ typedef ÀÌ´Ù. Çѹø¿¡ ó¸®ÇÒ À̺¥Æ® °¹¼ö¸¦ MAX_EVENTS·Î Á¤ÀÇÇÏ¿´´Âµ¥ ¿©±â¼­´Â 200 À» Á¤ÇÏ¿´´Ù (ÀûÁ¤ÇÑ °ªÀÎÁö´Â Àß ¸ð¸£°Ú´Ù).


constructor¿¡¼­, epoll ÃʱâÈ­ ¼º°ø¿©ºÎ¸¦ is_epoll_init º¯¼ö¿¡ ´ãÀ¸¹Ç·Î, °£´ÜÈ÷ °Ë»ç. ¹°·Ð epoll °¢ ÇÔ¼öµéµµ ¾ÈÀüÄÚµåµéÀ» ±¸ÇöÇϱâ´Â ÇßÁö¸¸ ?TEpoll ÀÌ ¸¹ÀÌ Ãß»óÈ­µÇ¾îÀÖÁö ¾ÊÀ¸¹Ç·Î ¿ª½Ã³ª ¸¸Á·½º·´Áö ¾ÊÀº ÄÚµåÀÌ´Ù.

listen ÀÛ¾÷ ¹× epoll Ãß°¡
    ....

    if((fd_listen = Listen(8000)) < 1){
        perror("listen error\n");
        exit(-1);
    }

    epoll.Add(fd_listen);
    .... 

¾Õ¼­ ÀÛ¼ºÇÑ Listen ÇÔ¼ö¸¦ ÄÝ. 8000 ¹ø Æ÷Æ®¸¦ listen Çϵµ·Ï ÇÏ°í, ¼º°ø½Ã¿¡ epoll ¿¡ ÀÌ fd ¸¦ µî·ÏÇÑ´Ù (Áï, ¿¬°á¿äûÀÌ µé¾î¿Ã°æ¿ì epoll ÀÌ °¨ÁöÇØ ³¾ °ÍÀÌ´Ù).

main loop ±¸Çö
    for(;;){
        n = epoll.Do(events, MAX_EVENTS, 10);
        for(i=0; i<n; ++i){
            if(events[i].data.fd == fd_listen){
                fd_client = accept(fd_listen, (struct sockaddr *) &client_addr, (socklen_t *) &addrlen);
                if(fd_client < 0){
                    perror("accept error\n");
                    continue;
                }
//                strcpy(cliaddr,inet_ntoa(client_addr.sin_addr));
                SetNonBlocking(fd_client);
                epoll.Add(fd_client);
            } else {
                if((result = OnEvent(events[i])) < 1){
                    printf("\n\nAn error is occured : %d", result);
                    close(events[i].data.fd);
                    epoll.Delete(events[i].data.fd);
                }
            }
        }
    }

    return 0;
} 

ÇÁ·Î±×·¥ÀÇ ¸ÞÀÎ ¹«ÇÑ ·çÇÁ. ¹Ýº¹Çؼ­ ?TEpoll.do ¸¦ ÄÝÇÑ´Ù. À̺¥Æ®°¡ ¹ß»ýÇÑ°æ¿ì ±× ¼ýÀÚ¸¸Å­ À̺¥Æ®¸¦ ó¸®Çϵµ·Ï ÇÑ´Ù. fdÀÇ ¼º°Ý¿¡ µû¶ó listen¼ÒÄÏ°ú ÀϹݼÒÄÏÀ» ±¸ºÐÇÏ¿´´Ù. »õ·Î¿î ¿¬°áÀÌ µé¾î¿Ã°æ¿ì ¼ÒÄÏÀ» nonblocking¸ðµå·Î º¯°æÇÏ°í¼­ epollÀÇ °ü½Éfd·Î µî·ÏÇÏ¿´°í, ÀϹݼÒÄÏ¿¡¼­´Â ?OnEvent·Î ±× 󸮸¦ ³Ñ°å´Ù. ¸¸¾à Á¾·á󸮰¡ ÇÊ¿äÇÑ °æ¿ì¸¦ À§ÇØ ?OnEventÀÇ °á°ú°ªÀ» ¹Þ¾Æ ?TEpoll.Delete ¸¦ È£ÃâÇϵµ·Ï Çß´Ù.

?TEpoll.Do ÀÇ ¼¼¹ø° ÆĶó¹ÌÅÍ´Â ´ë±â½Ã°£Àε¥, 10/1000ms·Î ÇÏ¿´´Ù. ÀÌ ¼ýÀÚ¸¦ 0 À¸·Î Çß´õ´Ï cpu »ç¿ë·üÀÌ 99.9%°¡ µÇ¾ú´Âµ¥ (½Ì±Û cpu), Àüü ÇÁ·Î¼¼½º ŸÀÓÀ¸·Î º¼¶§¿¡´Â À̺¥Æ®°¡ ¹ß»ýÇÏÁö ¾Ê°í ±×³É ´ë±âÇÏ´Â ½Ã°£ÀÌ °ÅÀÇ ÀüºÎÀ̹ǷΠ?TEpoll.Do ¸¸ ¾öû³ª°Ô È£ÃâÇØ´ë°í ÀÖ°Ô µÉ °ÍÀÌ´Ù. ³²´Â ½Ã°£Àº ¿î¿µÃ¼Á¦¿¡ µ¹·ÁÁÖµµ·Ï 10 Á¤µµ·Î Àâ¾Ò´Ù. ÃÊ´ç 100¹ø ?TEpoll.Do¸¦ È£ÃâÇÏ°Ô µÇ´Âµ¥ ¹Ð·Áµé¾î¿À´Â µ¥ÀÌŸ°¡ ¸¹´Ù¸é ¹°·Ð 1000¹øµµ ³Ñ°Ô È£ÃâµÉ ¼öµµ ÀÖ´Ù. ¿©±â¼­ 10ms¶ó´Â ¼ýÀÚ´Â À̺¥Æ®°¡ ¾øÀ»¶§ ÃÖ´ë À̸¸Å­¸¸ ±â´Ù·Á¶ó¶ó´Â Àǹ̷ΠÇؼ®ÇÑ´Ù. ¹«Á¶°Ç 10ms ±â´Ù¸®¶ó´Â ¶æÀº ¾Æ´Ï´Ù.

4 ¼Ò½ºÆÄÀÏ #

5 ÀÌÈÄ °³¼± #

?TEpoll Ŭ·¡½º°¡ ¸¹Àº Ãß»óÈ­¸¦ ÇÏ°í ÀÖÁö ¾ÊÀ¸¹Ç·Î, ¿©ÀüÈ÷ main ÇÁ·Î±×·¡¸Ó´Â epoll¿¡ ´ëÇØ ¼Ó¼ÓµéÀÌ ¾Ë°í ÀÖ¾î¾ß Çϸç ÀÌ°ÍÀº ¹Ù¶÷Á÷ÇÏÁö ¾Ê´Ù. ÇöÀçÀÇ ?TEpoll class¸¦ ±â¹ÝÀ¸·Î ÇÏ´Â ?TEpollSocketÀ» ¸¸µé°ÍÀÌ°í, ¿ÜºÎÀÎÅÍÆäÀ̽º´Â ÇÔ¼öÆ÷ÀÎÅ͸¦ ÀÌ¿ëÇÑ ÄݹéÀ¸·Î ±¸ÇöÇÒ °èȹ.

?TEpollSocketÀº listen, connect, accept¸¦ Æ÷ÇÔÇÏ°í À̺¥Æ®Æú¸µÀ» ÅëÇØ read, write, error À̺¥Æ®¸¦ °¨ÁöÇؼ­ »ç¿ëÀÚÀÇ ÇÔ¼ö¸¦ È£ÃâÇØÁÖµµ·Ï ÇÒ °ÍÀÌ´Ù.

last modified 2004-06-19 13:23:26
EditText|FindPage|DeletePage|LikePages|